Righthand’s DataSet Debugger Visualizer supports VS2013

Highlights from new version to 1.0.11.

  • added VS2013 version
  • added a "separated assembly" versions. Until now I was using RedGate's Smart Assembly to pack all referenced assemblies into a single DLL file for easier management and distribution. However, this black magic might cause problems in certain situations (Visual Studio add-ins screams for problems). Thus I've added another set that features assemblies in separate files. The bottom line, if you have problems or you want to be on the safe side, use the later set.

Go nuts!

A managed path to DirectCompute

About DirectCompute

After NVidia Cuda, OpenCL we got DirectX’s version (of GPGPU parallelism for numerical calculations) named DirectCompute. All three technologies are very similar and have one goal: to provide some sort of API and shader language for numerical calculations that GPGPU is capable of. And if you use it wisely the performance gains over normal CPU are huge, really huge. Not just that you offload CPU but the calculations due to GPGPU massive multithreading (and multicore) are much faster compared to even the most advanced x64 CPU.

It works like this: you prepare enough data that can be worked on in parallel, send it to GPGPU, wait till GPGPU finished processing the data and fetch the results back to the CPU where your application can use them. You can achieve up to a TFLOP with a graphics card sold today.

I guess this information is enough to see what is all about. For more information on the topic check out  Cuda and OpenCL. I’d suggest to check out the DirectCompute web site but the reality is that I couldn’t find any official (or non-official) page that deals with it (it is the youngest of the three but still that could be more online information, don’t you think). However you might check the DirectCompute PDC 2009 presentation here and a simple tutorial.

Of the three I am most interested in DirectCompute because:

  1. Cuda is tied to NVidia GPGPU while OpenCL and DirectCompute aren’t
  2. I prefer using DirectX over OpenGL for a simple reason – I did work for a client using DirectX so I am more familiar with it

I have a NVidia silent GeForce 9600 series graphic card (cards from GeForce 8 and up are supported) and the good news is that NVidia has been supporting CUDA for a while and recently introduced support for DirectCompute as well. OpenCL is also supported. I don’t know the current state of support for ATI cards.

There is a potential drawback if you go with DirectCompute though. It is a part of DirectX 11 and will run on Windows 7, Windows 2008 and Vista SP2 (somebody correct me). The problem is if you have an older Windows OS like Windows XP or you want support older Windows. In that case you might consider alternatives.

Goal

The not that good aspect of a young technology such as DirectCompute is lack of samples, documentation and tutorials are almost nonexistent. What’s even worse for a .net developer as I am is apparent lack of managed support. Which turns to be there to some extent through Windows API Code Pack (WACP) managed code wrappers. Note, WACP isn’t very .netish such as Managed DirectX was but it is good enough.

So I tried the managed approach for BasicCompute11 C++ sample (that comes with DirectX SDK) through WACP and here are the steps to make it run. It should give you a good starting point if you are DirectComputing through managed code and even if you are using native code. Hopefully somebody will benefit from my experience.

BasicCompute11 sample is really a simple one. It declares a type holding an int and a float, creates two arrays of those with an incremental value ( {0, 0.0}, {1, 1.1}, {2, 2.2}, ….{8191, 8191.0}) and adds them together to a third array.

I’ll be working on Windows 7 x64 with NVidia GeForce 9600 graphics card but will create a Win32 executable.

Steps

1. Install the latest NVidia graphics drivers. Current version 195.62 works well enough.

2. Install Windows 7 SDK. It is required because WACP uses its include files and libraries.

3. Make sure that Windows 7 SDK version is currently selected. You’ll have to run [Program Files]\Microsoft SDKs\Windows\v7.0\Setup\SDKSetup.exe. Note that I had to run it from command prompt because it didn’t work from UI for some reason.

4. Install DirectX SDK August 2009 SDK.

  • If it doesn't exist yet then declare an environment variable DXSDK_DIR that points to [Program Files (x86)]\Microsoft DirectX SDK (August 2009)\ path.
    image

5. Install Windows API Code Pack. Or better, copy the source to a folder on your computer. Open those sources and do the following:

  • Add $(DXSDK_DIR)Include path to Include folder
    image
  • And $(DXSDK_DIR)Lib\x86 to libraries
    image

After these settings the project should compile. However, there are additional steps, because one of the methods in there is flawed. Let’s correct it.

  • Open file Header Files\D3D11\Core\D3D11DeviceContext.h and find method declaration 
    Map(D3DResource^ resource, UInt32 subresource, D3D11::Map mapType, MapFlag mapFlags, MappedSubresource mappedResource);
    (there are no overloads to Map method). Convert it to
    MappedSubresource^ Map(D3DResource^ resource, UInt32 subresource, D3D11::Map mapType, MapFlag mapFlags);
  • Open file Source Files\D3D11\Core\D3D11DeviceContext.cpp and find the (same) method definition
    DeviceContext::Map(D3DResource^ resource, UInt32 subresource, D3D11::Map mapType, D3D11::MapFlag mapFlags, MappedSubresource mappedResource)
    Replace the entire method with this code:
    MappedSubresource^ DeviceContext::Map(D3DResource^ resource, UInt32 subresource, 
    D3D11::Map mapType, D3D11::MapFlag mapFlags) { D3D11_MAPPED_SUBRESOURCE mappedRes; CommonUtils::VerifyResult(GetInterface<ID3D11DeviceContext>()->Map( resource->GetInterface<ID3D11Resource>(), subresource, static_cast<D3D11_MAP>(mapType), static_cast<UINT>(mapFlags), &mappedRes)); return gcnew MappedSubresource(mappedRes); }

DirectX wrappers we need are now functional. Compile the project and close it.

6. Open DirectX Sample Browser (you’ll find it in Start\All Programs\Microsoft DirectX SDK (August 2009) and install BasicCompute11 sample somewhere on the disk.

image

7. Open the sample in Visual Studio 2008 and run it. The generated console output should look like this:

image Pay attention to the output because if DirectX can’t find an adequate hardware/driver support for DirectCompute it will run the code with a reference shader – using CPU not GPGPU (“No hardware Compute Shader capable device found, trying to create ref device.”) or even won’t run at all.

If the sample did run successfully it means that your environment supports DirectCompute. Good for you.

8. Now try running my test project (attached to this article) that is pure managed C# code. It more or less replicates the original BasicCompute11 sample which is a C++ project. The main differences with the original are two:

  • I removed the majority of device capability checking code (you’ll have to have compute shader functional or else…)
  • I compile compute shader code (HLSL –> FX) at design time rather at run time. This is required because there are no runtime compilation managed wrappers in WACP because those are part of D3DX which isn’t part of the OS but rather redistributed separately. So you have to rely on FXC compiler (part of DirectX SDK). A note here: I’ve lost quite a lot of time (again!) figuring out why FXC doesn’t find a suitable entry point to my compute shader code when compiling (and errors out). I finally remembered that I’ve stumbled upon this problem quite a long time ago: FXC compiles only ASCII(!!!!!) files. Guys, is this 2009 or 1979? Ben 10 would say. “Oh man.”
    Anyway, the FX code is included with project so you won’t have to compile it again. This time the output should look like this:
    image

I didn’t document my rewritten BasicCompute11 project. You can search for comments in the original project.

Conclusion

Compute shaders are incredibly powerful when it comes to numerical calculations. And being able to work with them through managed code is just great. Not a lot of developers will need their power though, but if/when they’ll need them the support is there.

As for final word: I miss documentations, tutorials and samples. Hopefully eventually they’ll come but for now there is a good book on CUDA (remember, the technologies are similar) – the book comes in a PDF format along NVidia CUDA SDK.

Have fun DirectComputing!

DirectComputeManaged.zip (2.05 mb)

Want to try Parallel Extensions on .net 3.5?

Check out Reactive Extensions to .NET (Rx). Looks like it includes “a back ported (and unsupported) release of Parallel Extensions for the .NET Framework 3.5 in the form of System.Threading.dll”. So, if you don’t have Visual Studio 2010 beta handy you might check it out and let us know how it goes. While you are there make sure you check out Rx as well as it looks an interesting and useful library once you grasp its concepts.

See the related blog post.

Dealing with iterations over null lists in LINQ to Objects

Problem

If you used LINQ to Objects you have certainly come across iterations over null values resulting in an ArgumentNullException being thrown at you.

See this example:

int[] b = null;
var query = from i in b select i;

In the case above the error is obvious but if the list comes as an argument of a method or some more complicated way it is hard to spot it. Sure, the obvious solution is an easy one. A simple if statement before will do it:

if (b != null)
    var query = from i in b select i;

What about nested loops? Like this

class Tubo
{
public List&lt;string> Strings;
}
...
IList&lt;Tubo> tubos = ...;
var query = from t in tubos
from s in t.Strings
select s;

Sure, we could add guardian clauses like the if before:

if (tubos != null)
     var query = from t in tubos
        where t.Strings != null
        from s in t.Strings
        select s;

The problem with this approach is that it gets cluttered and it complicates the flow, specially the first if.

Solution

So, here is my proposal and I am sure it has been proposed before (I just couldn’t find it on Google, err, I mean internet).

public static class Extension
{
public static IList&lt;T> Safe&lt;T>(this IList&lt;T> source)
{
if (source == null)
return new T[0];
else return source;
}
}

The extension method makes sure that query always gets a non-null list by making an empty one if it is null. The trick with extension method is that they can be invoked on null values which are passed as this argument.

And the last nested LINQ to Objects loop would look like:

var query = from t in tubos.Safe()
             from s in t.Strings.Safe()
             select s;

I am not sure that the extension method name Safe is adequate or not but it sure does help in code readability.

What do you say?

A better call to Control.Invoke

Whenever one needs to interact with WinForms UI from within another thread (the one that didn't create the UI controls) one has to rely on the Control.Invoke (or BeginInvoke/EndInvoke pair) method. Otherwise one gets an InvalidOperationException exception with message “Cross-thread operation not valid: Control ‘name here’ accessed from a thread other than the thread it was created on”. This happens because WinForms (and .net framework in general) isn’t thread safe.

Let’s say I want to know how many controls are on the form. I’d do it like this (Form f holds the instance of the Form created in some thread):

public static int GetControlsCount(Form f)
{
if (f.InvokeRequired)
return (int)f.Invoke(new Func<Form, int>(GetControlsCount), f);
else
return f.Controls.Count;
}
...
int count = GetControlsCount(f);

This way the method GetControlsCount is thread safe. That’s fine. But what should I do if I require to access many methods in such a thread safe way (I’ll blog about the reason I need it in a future post)? Creating this kind of wrapper for every different method I need to call would be kind of boring at best and difficult to maintain, don’t you think?

So I created a generic method instead, like this:

public static TRet InvokeSync<TRet>(Control control, Func<TRet> func)
{
if (control.InvokeRequired)
return (TRet)control.Invoke(func);
else
return func();
}
...
int count = InvokeSync<int>(f, () => f.Controls.Count);

This is much better because I don’t need to create a wrapper for each method – instead I merely provide a delegate (of type Func<int> in my case). There are two drawbacks to this approach.

1. It won’t work with different number of parameters nor it will work with methods (= actions) that don’t return a value. The only workaround is to create various similar methods that accepts different argument number and return either a result or no result (void). Here is a bunch of such variations:

public static void InvokeSync(Control control, Action action)
{
if (control.InvokeRequired)
control.Invoke(action);
else
action();
}
public static void InvokeSync<T>(Control control, Action<T> action, T argument)
{
if (control.InvokeRequired)
control.Invoke(action, argument);
else
action(argument);
}
public static TRet InvokeSync<T, TRet>(Control control, Func<T, TRet> func, T argument)
{
if (control.InvokeRequired)
return (TRet)control.Invoke(func, argument);
else
return func(argument);
}
public static TRet InvokeSync<T1, T2, TRet>(Control control, Func<T1, T2, TRet> func, T1 argument1, T2 argument2)
{
if (control.InvokeRequired)
return (TRet)control.Invoke(func, argument1, argument2);
else
return func(argument1, argument2);
}

2. Passing Control parameter (which is required to do the synchronization) is such pre .net 3.5-ish. Instead extensions methods can be used, like this:

public static class Extender
{
public static TRet InvokeSync<TRet>(this Control c, Func<TRet> func)
{
if (c.InvokeRequired)
return (TRet)c.Invoke(func);
else
return func();
}

public static void InvokeSync(this Control c, Action func)
{
if (c.InvokeRequired)
c.Invoke(func);
else
func();
}
}

So the final version of the call to InvokeSync looks even nicer:

int count = f.InvokeSync<int>(() => f.Controls.Count);

That’s it.

InvokeSyncExtender.zip (572.00 bytes)

Packing assemblies to a single file for Righthand.Dataset.Visualizer

A while ago I’ve created Righthand.DataSet.Visualizer, an advanced DataSet visualizer. Today I’ve added support for displaying a single table as well. It wasn’t a big deal but I guess people will find it useful.

Now, there is one things I weren’t too happy about until today: I reference a lot of DevExpress assemblies and I have to redistribute all those assemblies along mine two (my visualizer comes in form of two assemblies). Which makes a lot of assemblies in total and even worse, if two visualizers use slightly different DevExpress versions you are in for a trouble.

So I’ve decided to pack everything to a single file. ILMerge, a free assembly merging tool from Microsoft, won’t work for me since it has problems with reference to Microsoft.VisualStudio.DebuggerVisualizers even though I don’t want to redistribute it. So I tried Xenocode Postbuild for .NET which does all sort of hacky things with .net assemblies, it even allows to create a setup that doesn’t require .net framework installed at the target machine. Among other features (obfuscation, optimization, etc.) it provides an assembly merging option that I successfully used in my case. Here are the required steps for my case:

1. Start Xenocode Postbuild for .NET, click on Application tab. Use Add… button to add required assemblies to pack together (you can add assemblies individually or pick most important ones and then use Scan Dependencies button to add referenced ones):

application

2. If you want only to pack assemblies then use Null – For test and debugging purposes or any other preset you want, just make sure you set other options appropriately.

presets

 

 

 

3. On the Protection tab I did uncheck all metadata obfuscation (since I am not after obfuscation here) by right clicking on the root node and selecting Unselect Tree menu item. I don’t use any Disassembler Suppression either. I left moderate code obfuscation (level 3 in scale 0..4), just for testing – this option shouldn’t cause any trouble since it should keep functionality the same. If there are problems with the later it means that the tool sucks heavily.

protection

4. Clear all checkboxes in Optimize tab.

5. On the Output tab I made sure that Single application executable option in Link and Code Generation group is selected and Righthand.DebugerVisualizer.Dataset.Visualizer assembly is the main one. I also selected .\Setup for the output folder.

output

6. By clicking Xenocode Application button the final, single file, output is written to the disk.

And that’s it. I got a single file with all required assemblies packed together. Just that easy. Note that I intentionally used only a fraction of Postbuild power.

If you use frequently Postbuild you should also consider using Final Builder tool, an automated build and release management tool that supports Postbuild out of the box (I am sure other such tools support Postbuild as well).

And finally, here is the updated visualizer:

RightHand.DebugerVisualizer.Dataset.Visualizer 0.9.14.zip (7.60 mb)

Let me know if there are any problems or if you have any improvement wish.

Using XtraChart ASP.NET control in an ASP.NET MVC project

The problem

These days I am building an ASP.NET MVC project that requires charting. The problem is that there are no native ASP.NET MVC charting controls out there. The only one I am aware of is the one from Syncfusion . The problem with it is that it is in a beta and I didn’t have time to test it out. BTW, Syncfusion is the only 3rd party control provider (in beta though) for ASP.NET MVC AFAIK.

The solution

Anyway, back to my problem – charting in ASP.NET MVC. It is quite obvious that I have to use an ASP.NET control for the job. And since I already own and I am used to XtraCharts I’ve decided to give it a try (alternatives include use of Microsoft’s free ASP.NET Chart Control (which works in ASP.NET MVC for sure) and other ASP.NET charting controls might work as well). And guess what: XtraCharts works without many problems. As an image provider that is – I don’t need callbacks nor I think they are supported in this scenario.

Creating a test project

There are couple of extra steps necessary to use XtraCharts in ASP.NET MVC project. Here are steps necessary to create a test project.

Requirements: XtraCharts v9.1.

1. Drop a WebChartControl toolbox item (residing in DX.9.1.: Data Toolbox’ tab) on the Index view (I tested with the view (aspx) but it should work with partial view (ascx) as well). You’ll get this code:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register Assembly="DevExpress.XtraCharts.v9.1.Web, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts.Web" TagPrefix="dxchartsui" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%
   1: = Html.Encode(ViewData["Message"]) 































































%></h2>































































<p>































































To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.































































</p>































































<dxchartsui:WebChartControl ID="WebChartControl1" runat="server">































































</dxchartsui:WebChartControl>































































</asp:Content>
































It might happen that all the necessary assemblies won’t be referenced automatically. In this case add manually these (v9.1.x) assemblies:

  1. DevExpress.Web
  2. DevExpress.Charts.Core
  3. DevExpress.XtraCharts

2. Adjust WebChartControl’s settings either directly or through designer (yes, you can use its designer!). I’ll create a 3D pie chart with a single series bound to Name/Value pair. Disable both EnableCallbacks and EnableViewState.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register Assembly="DevExpress.XtraCharts.v9.1.Web, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts.Web" TagPrefix="dxchartsui" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%
   1: = Html.Encode(ViewData["Message"]) 































































%></h2>































































<p>































































To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.































































</p>































































<dxchartsui:WebChartControl ID="someChart" runat="server" EnableViewState="false" EnableCallbacks="false"































































DiagramTypeName="SimpleDiagram3D" Height="200px" Width="300px">































































<SeriesSerializable>































































<series argumentdatamember="Name" labeltypename="Pie3DSeriesLabel" name="Series 1"































































pointoptionstypename="PiePointOptions" seriesviewtypename="Pie3DSeriesView" valuedatamembersserializable="Value">































































<view hiddenserializablestring="to be serialized"></view>































































<label hiddenserializablestring="to be serialized" linevisible="True" overlappingoptionstypename="OverlappingOptions">































































<fillstyle filloptionstypename="SolidFillOptions">































































<options hiddenserializablestring="to be serialized"></options>































































</fillstyle>































































</label>































































<pointoptions hiddenserializablestring="to be serialized"></pointoptions>































































<legendpointoptions hiddenserializablestring="to be serialized"></legendpointoptions>































































</series>































































</SeriesSerializable>































































<SeriesTemplate LabelTypeName="Pie3DSeriesLabel" PointOptionsTypeName="PiePointOptions"































































SeriesViewTypeName="Pie3DSeriesView">































































<View HiddenSerializableString="to be serialized">































































</View>































































<Label HiddenSerializableString="to be serialized" LineVisible="True" OverlappingOptionsTypeName="OverlappingOptions">































































<FillStyle FillOptionsTypeName="SolidFillOptions">































































<Options HiddenSerializableString="to be serialized"></Options>































































</FillStyle>































































</Label>































































<PointOptions HiddenSerializableString="to be serialized">































































</PointOptions>































































<LegendPointOptions HiddenSerializableString="to be serialized">































































</LegendPointOptions>































































</SeriesTemplate>































































<Diagram RotationMatrixSerializable="1;0;0;0;0;0.5;-0.866025403784439;0;0;0.866025403784439;0.5;0;0;0;0;1">































































</Diagram>































































<FillStyle FillOptionsTypeName="SolidFillOptions">































































<Options HiddenSerializableString="to be serialized"></Options>































































</FillStyle>































































</dxchartsui:WebChartControl>































































</asp:Content>
































































3. Add the following registration on the top of the page:

<%@ Register Assembly="DevExpress.XtraCharts.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts" TagPrefix="dx" %>

and change nodes of type <series> to type <dx:series>. Otherwise you’ll have a naming conflict.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register Assembly="DevExpress.XtraCharts.v9.1.Web, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts.Web" TagPrefix="dxchartsui" %>
<%@ Register Assembly="DevExpress.XtraCharts.v9.1, Version=9.1.3.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a"
Namespace="DevExpress.XtraCharts" TagPrefix="dx" %>
<asp:Content ID="indexTitle" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2><%
   1: = Html.Encode(ViewData["Message"]) 































































%></h2>































































<p>































































To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.































































</p>































































<dxchartsui:WebChartControl ID="someChart" runat="server" EnableViewState="false" EnableCallbacks="false"































































DiagramTypeName="SimpleDiagram3D" Height="200px" Width="300px">































































<SeriesSerializable>































































<dx:series argumentdatamember="Name" labeltypename="Pie3DSeriesLabel" name="Series 1"































































pointoptionstypename="PiePointOptions" seriesviewtypename="Pie3DSeriesView" valuedatamembersserializable="Value">































































<view hiddenserializablestring="to be serialized"></view>































































<label hiddenserializablestring="to be serialized" linevisible="True" overlappingoptionstypename="OverlappingOptions">































































<fillstyle filloptionstypename="SolidFillOptions">































































<options hiddenserializablestring="to be serialized"></options>































































</fillstyle>































































</label>































































<pointoptions hiddenserializablestring="to be serialized"></pointoptions>































































<legendpointoptions hiddenserializablestring="to be serialized"></legendpointoptions>































































</dx:series>































































</SeriesSerializable>































































<SeriesTemplate LabelTypeName="Pie3DSeriesLabel" PointOptionsTypeName="PiePointOptions"































































SeriesViewTypeName="Pie3DSeriesView">































































<View HiddenSerializableString="to be serialized">































































</View>































































<Label HiddenSerializableString="to be serialized" LineVisible="True" OverlappingOptionsTypeName="OverlappingOptions">































































<FillStyle FillOptionsTypeName="SolidFillOptions">































































<Options HiddenSerializableString="to be serialized"></Options>































































</FillStyle>































































</Label>































































<PointOptions HiddenSerializableString="to be serialized">































































</PointOptions>































































<LegendPointOptions HiddenSerializableString="to be serialized">































































</LegendPointOptions>































































</SeriesTemplate>































































<Diagram RotationMatrixSerializable="1;0;0;0;0;0.5;-0.866025403784439;0;0;0.866025403784439;0.5;0;0;0;0;1">































































</Diagram>































































<FillStyle FillOptionsTypeName="SolidFillOptions">































































<Options HiddenSerializableString="to be serialized"></Options>































































</FillStyle>































































</dxchartsui:WebChartControl>































































</asp:Content>
































































4. Under Models folder create RhData class that will hold data:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication10.Models
{
public class RhData
{
public string Name { get; set; }
public int Value { get; set; }
}
}

5. Add class Index.aspx.cs next to Index.aspx file. This will serve as codebehind file. Also add Page_Load method, create and bind data to chart right in there. Note that you have to declare chart instance field as well since the designer won’t do it for you.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcApplication10.Models;
namespace MvcApplication10.Views.Home
{
public class Index: ViewPage
{
protected global::DevExpress.XtraCharts.Web.WebChartControl someChart;
protected void Page_Load(object sender, EventArgs e)
{
List<RhData> data = new List<RhData>();
data.Add(new RhData { Name = "One", Value = 1 });
data.Add(new RhData { Name = "Two", Value = 2 });
someChart.DataSource = data;
someChart.DataBind();
}
}
}

Note: The proper MVC to provide data way would be through the model, however for the sake of simplicity I took this shortcut. The binding itself has to be done in Page_Load event.

6. Wire up the code behind class to the view by adding CodeBehind attribute and modifying Inherits one.

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="MvcApplication10.Views.Home.Index" CodeBehind="Index.aspx.cs" %>

 

 

The result

If everything goes well you should see such output.

demo

This will do just fine until there is an MvcXtraChart control I guess.

XtraChartsMvc.zip (241.46 kb) (Updated) Note: Built with DevExpress v9.1.3.0. If you use other version then you should run DX' ProjectConverter tool or just do a search and replace of "9.1.3.0" with your version.

Shout it