North American Sales: 1-800-231-8588
Global Contacts
My Account
Menu
North American Sales: 1-800-321-8588
My Account
Sign In/Register
Design & Development
Design & Develop
Best Value
Infragistics Ultimate
The complete toolkit for building high performing web, mobile and desktop apps.
Indigo.Design
Use a unified platform for visual design, UX prototyping, code generation and application development.
Web
Ignite UI for Angular
Ignite UI for JavaScript
Ignite UI for React
Ultimate UI for ASP.NET
Indigo.Design
Desktop
Ultimate UI for Windows Forms
Ultimate UI for WPF
Prototyping
Indigo.Design
Mobile
Ultimate UI for Xamarin
Ultimate UI for iOS
Ultimate UI for Android
Automated Testing Tools
Test Automation for Micro Focus UFT: Windows Forms
Test Automation for Micro Focus UFT: WPF
Test Automation for IBM RFT: Windows Forms
UX
Indigo.Design Desktop
Collaborative prototyping and remote usability testing for UX & usability professionals
Indigo.Design
A Unified Platform for Visual Design, UX Prototyping, Code Generation, and App Development
Business Intelligence
Reveal Embedded
Accelerate your time to market with powerful, beautiful dashboards into your apps
Reveal App
Empower everyone in your organization to use data to make smarter business decisions
Team Productivity
Learn & Support
Support
Help & Support Documents
Blogs
Forums
Product Ideas
Reference Applications
Customer Stories
Webinars
eBook & Whitepapers
Events
Free Trials
Pricing
Product Pricing / Buy Online
Renew Existing License
Contact Us
Forums
Ultimate UI for WPF
Your Privacy Matters
: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use.
Cookie Policy
Close
State
Not Answered
Replies
6 replies
Subscribers
8 subscribers
Views
1710828 views
Users
0 members are here
Data Binding
broken
XamChart (Retired)
Share
More
Cancel
115
XamChart RenderTargetBitmap and DataBinding: Broken...
Jody Breshears
posted
over 16 years ago
I am writing an application where I must render a bitmap of a chart without in any way visually displaying it (so no adding it to the visual tree.) The only technique I have seen so far involves using a RenderTargetBitmap to do so.
In a previous post, [Infragistics] Andrew Smith posted code which purported to solve this problem. It worked, but only if you did no data binding. I have modified it to the following state to demonstrate the problem. (You should simply be able to paste this code into a class file, and add the appropriate references. The class extends window, so simply run the project to see the result.)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Infragistics.Windows.Chart;
public class VisualChildWindow : Window {
public VisualChildWindow() {
XamChart testChart = new XamChart();
testChart.DataBind += chart_DataBind;
testChart.BeginInit();
testChart.Width = 400;
testChart.Height = 200;
testChart.EndInit();
addSeriesAndData(testChart);
testChart.Measure(new Size(400, 200));
testChart.Refresh();
testChart.Arrange(new Rect(0, 0, 400, 200));
testChart.UpdateLayout();
RenderTargetBitmap bmp = new RenderTargetBitmap(400, 200, 96, 96, PixelFormats.Pbgra32);
bmp.Render(testChart);
Image image = new Image() { Source = bmp };
image.Stretch = Stretch.None;
// Content = testChart;
Content = image;
Panel panel;
}
void chart_DataBind(object sender, DataBindEventArgs e) {
}
private void addSeriesAndData(XamChart chart) {
var series = new Series();
series.DataSource = new ArrayList { new{number = 1}, new{number = 2}, new{number = 4.6} };
series.DataMapping = "Value=number";
chart.Series.Add(series);
chart.DataSourceRefresh();
}
[STAThread]
public static void Main() {
var window = new VisualChildWindow();
var app = new Application();
app.Run(window);
}
}
Near the bottom of the main method, you will see two different lines, one setting Content to the chart, the other the image. You can swap them back and forth. If you set the chart as the content, you can verify that it is rendering correctly. Swap them back to test the image.
Finally, you will see a call to addSeriesAndDatabind(). This method sets up the databinding. If you comment it out, you get the default rendering of the chart.
Now to the problem. Comment out the call to addSeriesAndDatabind(), and run. You will see the chart gets rendered correctly as an image. Restore the call to addSeriesAndDatabind() and run, and you will see the chart render itself, but with no data. If you put a breakpoint on chart_DataBind() (which I have wired up as a handler for DataBind()) you will see that it never gets called. Notice also that I am already calling chart.DataSourceRefresh(), which according to the documentation is supposed to force a refresh.
It looks for all the world as though if only I could force the chart to databind, I'd be home free. I can't seem to do that, however. Perhaps somebody at infragistics can give a little more insight as to the life of this control. Or better yet, take the above source code and make it work.
Thanks,
Jody
115
Jody Breshears
posted
over 16 years ago
If anybody is still reading this thread, I found the solution. The class below shows what I believe are the Canonical steps to get a XamChart to render to a bitmap. Note that this is done within a test, and the class does not extend Window. This means you can do this entirely behind the scenes, without reference to visual or logical trees.
The magic is in the getFixedChart method. This method shows the order of operations, and order is crucial. You must call BeginInit & EndInit,
then
Measure & Arrange,
then
DataSourceRefresh. This call will fire DataBind(), so be aware. After DataBind() returns (assuming you are trapping that event) you
must
finally call Refresh and UpdateLayout. At this point, the chart should be fully constructed, and ready to go.
The first test ("RunIt") shows the sequence.
There is nothing wrong between XamChart and RenderTargetBitmap. I believe all the previous troubles reported were due to the fact that the chart was simply not rendering. Once the chart is forced to render, it goes to a bitmap with no troubles. It turns out that XamChart is working correctly.
BTW, Infragistics, it would have been nice to find some of this in the documentation. Maybe a little less Xaml and little more meat next time, eh? It would also be nice if we could make the Chart throw a useful exception, rather simply render blank.
using System;
using System.Collections;
using System.IO;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Infragistics.Windows.Chart;
using NUnit.Framework;
namespace DataBindingTests {
[TestFixture]
public class Canonical {
private const string imageFileName = "imageCan.png";
[Test]
public void runIt() {
XamChart chart = getFixedChart(800, 500);
BitmapSource bmp = getBitmap(chart, 800, 500);
writeToFile(bmp);
}
private XamChart getFixedChart(int width, int height) {
XamChart chart = new XamChart();
chart.BeginInit();
chart.Width = width;
chart.Height = height;
chart.View3D = false;
getDataSeries(chart);
chart.EndInit();
chart.Measure(new Size(width, height));
chart.Arrange(new Rect(0, 0, width, height));
chart.DataSourceRefresh();
chart.Refresh();
chart.UpdateLayout();
return chart;
}
private BitmapSource getBitmap(Visual testChart, int width, int height) {
RenderTargetBitmap bmp = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
bmp.Render(testChart);
return bmp;
}
private void getDataSeries(XamChart chart) {
var series = new Series();
series.DataSource = new ArrayList { new { number = 1, name = "Peter" }, new { number = 2, name = "Susan" }, new { number = 4.6, name = "Edmund" }, new { number = 14.6, name = "Lucy" } };
series.DataMapping = "Value=number; Label=name";
series.Label = "Test Data";
chart.Series.Add(series);
}
private void writeToFile(BitmapSource bmp) {
File.Delete(imageFileName);
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create(bmp));
FileStream stream = new FileStream(imageFileName, FileMode.Create);
encoder.Save(stream);
stream.Flush();
stream.Close();
}
}
}
Cancel
Reply
Cancel
<