Blogs

WPF

  • TechEd Online video is available about Functional Programming in C#

         

    Video: TechEd Talk on Functional Programming in C# Yesterday I recorded a video at TechEd about Functional Programming in C#, together with my colleague Gary Short. It’s up on the site now: Functional Programming in C#.

    Unfortunately, the quality of the code demo in the video isn’t that great, my apologies for that. I’m not even going to go into what they made me do to the Apple logo on my laptop :-)

    The info at the end of the video is supposed to read something like this:

    Have fun, and let me know what you think!

  • TechEd 2009, the first two days

         

    TechEd 2009 has been great so far. It is my job to do WPF presentations as part of the giveaway game we are doing, and I got a lot of good feedback on them. Our suite is on a good level overall, with the controls you need to set up a business application, from basic navigation, docking and similar "pluming" on to data analysis controls in the shape of the DXGrid and the DXCharts.

    The audience appears to be mixed: of course there's still, as ever, the general distinction between web and client side devs, but there's also a distinction now between those people who are dabbling in Microsofts new UI technologies Silverlight and WPF, and those who are not. Interest in these platforms is generally good though, so I had quite a lot to do with my WPF demonstrations. The controls are very stable by now, and they are all going to be part of our 9.2 release, roughly scheduled for early July at this time.

    Today I also did my BOF session on parallelization and functional programming, which went great - thanks to everybody who was there! I recorded a TechEd Online video together with Gary, which they claim will be online tomorrow. Stay tuned for a link!

  • DevExpress at TechEd US next week - meet us there and win!

         

    As some of you might have noticed from the forums and blogs, Twitter and other news outlets, many of us at DevExpress are currently in LA, preparing everything for TechEd next week. It's going to be a great event again and you can make it better by coming to our booth! It's number 201, and of course it's really cool and huge, as I hear, so we shouldn't be hard to find.

    We're going to focus on our 9.1 product versions for presentations at the event (find the news for 9.1 here, if you haven't seen them yet), but of course we'll be able to answer any questions you can throw at us. We've also got a session scheduled for Wednesday, starting at 4:30pm in room 404, where Mark and I are going to give an overview of all the products that DevExpress offers - well, most of them at least. Controls for data entry, data viewing, analysis, reporting, charting, navigation, for Windows Forms, ASP.NET, Silverlight, WPF, and of course the IDE tools and frameworks - the list seems to grow continuously, and if you haven't had a chance to see all this for yourself, TechEd is a great opportunity.

    Last but not least, you have a chance to win great big things at our booth. I hear I'm not supposed to tell everybody yet what they are, but I think I can say that they are, well, big. And great. And a lot of fun. Stay tuned for more information or, again, make sure to stop by next week and see for yourself.

  • Live from ACCU Conference - the high horse

         

    ACCU Conference just got started, and I'm sitting here listening to the keynote - Uncle Bob Martin about The Birth of Craftsmanship. Interesting. Yes, as the picture hints (and I apologize for its quality), he started out talking about electron guns and slits.

    In spite of Robert Martin, the most interesting thing about this conference, from my point of view, is the group of people that comes there. Well, of course the people who attend conferences are always the most interesting thing, if you go to conferences as a speaker or exhibitor. But this case is special, because it proves something I've suspected for a while: there's life outside of .NET!

    Of course I'm exaggerating. Everybody knows that there's life outside .NET. Right? Well, I do think that when we work on any particular platform for a good while, we tend to forget that there are others in the world who do something entirely different. Or, if we do realize that, we forget that these other people aren't all stupid, wasting their time, hacking around on unimportant stuff.

    I suspect we're all guilty of that. At the same time, I've found that these people I'm talking to here, many of whom specialize in native code C++ development (just to name one example of a horrible outdated time wasting mechanism, from the perspective of many .NET developers), seem to be a lot more open towards, and better informed about, things that go on outside their own world.

    Maybe they have to. Maybe they just realize that the thing they do themselves isn't the most important and relevant one in the world, and they just feel the need to keep up to date about other things. But... do you think they might also benefit from looking outside their box? I do.

    .NET has been evolving quickly over several years, and there are lots of voices criticizing that pace - for everyone of us, it's hard to keep up with the news that constantly come out of MS. At the same time, it's important to realize that the largest part of news put out by Microsoft aren't really news. I'm not accusing Microsoft of anything -- I believe they are doing a good job bringing certain technology into the mainstream, whether it's been invented by them or not. My point is that there's no reason to be surprised all the time.

    My point is that if most of us had a less exaggerated opinion about the thing we do in the context of everything else, we would go learn about the rest of the world much more. We would spend less time being surprised and more time making well-informed decisions and being efficient. I suspect most of you would make the same statement about themselves as I would: I've always been thinking out of the box, and all this isn't news to me. Well, I don't think any of us is really where we should be in this regard. If you think you are, let me know and I will look up to you from now on :-)

  • Overheard at DevWeek: There's too much technology in the world

         

    My workshop day at DevWeek is over, and I'm waiting for Thursday to do my remaining three sessions on C# and F#. I've had a number of good conversations here – thanks to everybody who came up to me and said hi!

    For no apparent reason, one common theme has crept up several times in discussions I've had this week, both with other speakers and with attendees of the conference. It's the topic of technology evolution, and the associated difficulties people have to keep up to date. Generally, there appear to be three types of programmers in the world (tongue in cheek, slightly):

    1. The ones who are interested in technology and chose a career in that area because they've always been interested. Of course they can be overwhelmed by the amount of new technology all around them, but type 1 programmers regard it as a challenge because it's part of their mission in life.
    2. The ones who have a personal life which doesn't (only) involve computers, but who recognize that regardless of the job they have or the opinions of their employers, it's in their own best interest to learn about new technology sooner rather than later. So they go to community events or pay their own ticket for a conference like DevWeek. They spend time reading blogs and stackoverflow.com.
    3. The ones for whom programming is a 9-5 (insert local standard working hours here) job. They look at technology as a tool. The tool is given to them by their employer, and they don't necessarily know how to use it very well. They aren't interested personally, so they pass on training opportunities half the time. If their employer gives them a new or changed tool, they hate him for it, because it makes their work more difficult. On average they live much longer than types 1 and 2.

    The reality is today that there are far more type 3 programmers in the world than types 1 and 2. They tend to form large teams as well. Teaching any single type 3 programmer something really exciting and new, like maybe nullable types or even generics, is quite a hard job, but for large teams of them it's practically impossible, which puts some people in the industry in a pretty difficult position.

    Take consultants. They come to a customer, analyze the situation, and find that the best solution would be to create a little Ruby on Rails application. They suggest that to the customer, who thinks it's the most hilarious thing he's recently heard. Next time, they might not even suggest the same thing. And it doesn't have to be anything esoteric like Ruby, it could be new programming language features that some of us have been using for about 5 years now in VB.NET or C#.

    Finally, take component/library vendors like DevExpress. Sometimes we see the need to move on, so for instance we start using Generics – and since we asked back then, we know that there's a good percentage of our customers who likes that we made that step. But how large is the group of people out there who doesn't consider using any 3rd party controls because they don't understand half the technology that these products are based on? I honestly don't know how big this problem is today, but one thing I'm pretty sure about: it's not going to get better on its own. There's hardly anything we can do about it. Maybe Microsoft, the company that defines the programming world most of us live in, should spend some time thinking about this and coming up with ideas. I guess if I asked, they might say they already do this. Doesn't seem to work very well, though.

  • Speaking at DevWeek 2009

         

    I’ll be traveling down to London tomorrow for DevWeek 2009, where I’m going to do a workshop on F# on Monday and a few sessions on C# and F# on Thursday.

    Are you going to DevWeek? Are you going to be in London over the next few days? If you want to meet up, just let me know and I’m sure we can work something out!

    I’ll be twittering while I’m there, so following me on Twitter will be a good way of finding out where I am, if you fancy joining me for a pint!

  • When in Rome...

         

    ... do like the Romans do. That's what they say, isn't it? Well, I'm not sure I've met too many Romans, since it's hard for me to distinguish them from the other Italians. But one of the cases where I'm pretty sure about somebody being Roman would be the taxi driver who got me to the hotel from the airport, and I'd rather not do as he did – more to the point, I think I'd be arrested pretty quickly in most countries if I did!

    Anyway, I survived, and now I'm waiting to do my sessions in the afternoon today. About 90 people signed up for the main event apparently, and another 50 or so turned up yesterday evening for the community sessions. The same will happen tonight, so it's really a 12 hour day altogether for those attendees who stay for the duration. Quite a marathon!

    Finally, now I know what Gary was always getting at with his comments about the Germans. He says they go "gibberish gibberish Visual Studio gibberish" all the time – and he's right, that's exactly what Italians sound like to me! Funny how the languages mix when it comes to technology. Apparently even Microsoft doesn't see the need to translate product and technology names into non-English languages... I guess that's a good thing. An automated translation service tells me that .NET would otherwise be "red punteadapunteggiare la rete" in Italian, which doesn't sound like an improvement to me. :-)

  • Basta! Italia next week

         

    I'm going to be at Basta! Italia next week, in Rome, delivering talks about C# as well as LINQ extensibility. If you're there, say hi and let's discuss DevExpress technology!

  • DevExpress WPF Grid Control - Editing Data - the missing pieces

         

    In a previous post, I was looking at editing data with the WPF Grid. Unfortunately I stumbled upon a few issues with editor configuration back then. With 9.1 being tested internally, I decided it would be time to have a fresh look at things, and finally post an example on the configuration on editor type properties. As you will see, all is not perfect yet - but that's what testing phases are good for, of course.

    Without further ado, here's how to configure settings for a column's editor:

    <dxg:GridColumn FieldName="Population">

        <dxg:GridColumn.EditSettings>

            <dxe:ButtonEditSettings>

                <dxe:ButtonEditSettings.Buttons>

                    <dxe:ButtonEditButtonInfo ButtonKind="Regular" Click="ButtonEditButtonInfo_Click" />

                </dxe:ButtonEditSettings.Buttons>

            </dxe:ButtonEditSettings>

        </dxg:GridColumn.EditSettings>

    </dxg:GridColumn>

    There are several pre-configured settings types, plus you can derive your own. These encapsulate both the editor to be used and its own settings, so deriving your own settings objects is a good way of creating reusable pre-configured editors.

    In the case of the sample code above - well - as you can see, we'll need to fix something about those two buttons that come up although I configured only one. Hm.

    Update: As these things go, the solution to this button issue was found almost immediately after I posted this article. It's not a bug, it's a feature! Well, at least it's something that has been done for certain technical reasons surrounding the design time control initialization/persistence mechanisms in WPF. So, to get rid of the one button that is included by default, the ButtonEditSettings instance must be configured like this (note the AllowDefaultButton attribute!):

    <dxe:ButtonEditSettings AllowDefaultButton="False">

        <dxe:ButtonEditSettings.Buttons>

            <dxe:ButtonEditButtonInfo ButtonKind="Regular" Click="ButtonEditButtonInfo_Click" />

        </dxe:ButtonEditSettings.Buttons>

    </dxe:ButtonEditSettings>

    There are also several markup extensions included with the Grid control, which provide a shortcut for certain editor configurations. As an example (and this is not in my demo for this post, it's from our WPF grid demo that comes with DXperience 9.1), you could have a GridColumn that looks like this:

    <dxg:GridColumn FieldName="ToId" Header ="To" SortMode="DisplayText" Width="100"

                   EditSettings="{dxe:ComboBoxSettings IsTextEditable=false, ValueMember=Id,

                   DisplayMember=Name, ItemsSource={x:Static local:OutlookData.Users}}" />

    Unfortunately I don't think that all these options are fully documented yet - we are still in a pre-release phase after all. This blog isn't the right place for such docs either, so for the time being I can only recommend to have a good look around our libraries as well as demos, to pick up hints on what is possible. Docs will follow, promise!

    Here's the sample code for this post: DxGridEditing2.zip

    Please note that the sample is built for DXperience 9.1! I'm afraid you may have to wait just a little while longer to try it out yourself. It should be possible to use 8.3.x, but I haven't tried that - YMMV.

  • DevExpress WPF Grid Control - Editing Data

         

    Prompted by a forum post, I decided to have a look at how inplace editing works in the DXGrid for WPF. Good results – it's really easy.

    The first interesting thing to realize is that editing is actually active by default in the grid. Nevertheless, the end user can't edit anything unless one setting is changed: the property NavigationStyle on the View must be changed to CellNavigation (by default it's RowNavigation). As soon as this setting is changed, editing becomes possible, since both the AllowEditing on the GridControl itself and the GridColumnView instance are True by default.

    Here's my minimum XAML snippet that results in an editable grid. I'm using the same country datasource that I was using in my first DXGrid blog post.

    <Window x:Class="DxGridEditing.Window1"

       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       xmlns:local="clr-namespace:DxGridEditing"

       Title="Window1" Height="342" Width="534" xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid" xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors">

        <Window.Resources>

            <local:CountryInfoList x:Key="list" />

        </Window.Resources>

        <DockPanel>

            <dxg:GridControl Name="gridControl1" AutoPopulateColumns="True" DataSource="{StaticResource list}">

                <dxg:GridControl.View>

                    <dxg:GridColumnView NavigationStyle="CellNavigation" />

                </dxg:GridControl.View>

            </dxg:GridControl>

        </DockPanel>

    </Window>

    The default being what it is, the question is obviously how to go about changing that. The first thing I want to do is switch off editing for one or more columns. In my code, I've been using automatic column creation so far, and I have to switch over to pre-configured columns in order to do this. Easy enough to do – get rid of the AutoPopulateColumns attribute on the GridControl and add a few GridColumn instances instead (bring up the GUI editor for the GridControl.Columns property if you don't like to do the typing).

    <dxg:GridControl Name="gridControl1" DataSource="{StaticResource list}">

        <dxg:GridControl.Columns>

            <dxg:GridColumn FieldName="Name" />

            <dxg:GridColumn FieldName="AreaKM2" />

            <dxg:GridColumn FieldName="Population" />

        </dxg:GridControl.Columns>

        <dxg:GridControl.View>

            <dxg:GridColumnView NavigationStyle="CellNavigation" />

        </dxg:GridControl.View>

    </dxg:GridControl>

    From this point, it's easy to configure per-column settings, and that includes whether or not a certain column can actually be edited. The AllowEditing settings on the GridControl and the GridColumnView act as defaults, but each column has the final word when a decision about editing must be made.

    There are two settings that come in handy. First, the column also has an AllowEditing property, and it's default value is Default, meaning it takes its value from its parent. Setting this to False (assuming the parent default is True) disables editing for this column entirely. As an alternative, there's also a ReadOnly property, which I personally find very useful – in a situation where some grid columns are editable, it's often sensitive to allow the user access to the values in the other, non-editable columns, for copying to the clipboard. Leaving AllowEditing on its Default value, but setting ReadOnly to True has the result that the editor for a column is still available, but the value can't be changed.

    <dxg:GridControl.Columns>

        <dxg:GridColumn FieldName="Name" />

        <!-- Using both ReadOnly and AllowEditing at the same time

             doesn't really make too much sense, unless the idea is

             to override the parent default for AllowEditing. In

             this case I just left both in place for illustration

             purposes.

        -->

        <dxg:GridColumn FieldName="AreaKM2" ReadOnly="True" AllowEditing="False" />

        <dxg:GridColumn FieldName="Population" />

    </dxg:GridControl.Columns>

    The final thing I want to mention here is the configuration of the EditSettings property. The settings that are provided out of the box (TextEditSettings, CheckEditSettings, ComboBoxEditSettings and DateEditSettings) encapsulate the editor types that our grid supports at the time of writing. So it's important to be aware of this setting, because it defines which editor will be used.

    I was going to continue for a bit by mentioning a few of the customizations that can be made to the editing settings, but I stumbled upon a few issues that need research. I'll continue with more details a bit later.

    Here is the download of the sample project: DxGridEditing.zip

  • Getting started with the DevExpress datagrid for WPF - XPO data binding

         

    This time I'm trying to use the DXGrid for WPF with XPO. There are at least two different approaches I'm going to try, and I found a few small issues on the way as well.

    In my demo project (see the download at the bottom) I have created a few persistent classes and a routine to create some test data (in SQL Server by default). As it turned out, I didn't use more than the Customer and Order classes in the grids, but I left the rest in place anyway. A Customer has a Name and a collection of Orders. An Order has a Date and a collection of OrderLines (but the OrderLines are irrelevant here).

    Generally, hooking up a WPF grid to an XPCollection<T> is easy. I create the following grid in my window:

    <dxg:GridControl Name="customerGrid" AutoPopulateColumns="True">
      <dxg:GridControl.View>
        <dxg:GridColumnView />
      </dxg:GridControl.View>
    </dxg:GridControl>

    Then, in code, I add this :

    UnitOfWork uow;

    protected override void OnInitialized(EventArgs e) {
      base.OnInitialized(e);

      uow = new UnitOfWork();
      customerGrid.DataSource = new XPCollection<Customer>(uow);
    }

    That's it, for a start - running the application at this point results in a grid showing me Customer objects. Now, what I want to do is add another grid that shows the related orders for the customer selected in the first grid. Easy enough, one might think - with standard WPF controls, I would typically bind the second control like this: ItemsSource="{Binding ElementName=customerGrid,Path=SelectedItem.Orders}". (Did I get that right? Just wrote it down from the top of my head - it's not really important.)

    Not quite so easy with the DXGrid, or at least it doesn't look that easy at first glance. As Thomas Grusche commented on my previous post, the DXGrid doesn't derive from ItemsControl, so the binding will have to look a little different. The property to bind to is DataSource, and to get hold of the selected object in the grid, the path must be this: View.CurrentRowData.DataContext

    Cool, so my first try looked like this: DataSource="{Binding ElementName=customerGrid,Path=View.CurrentRowData.DataContext.Orders}". It didn't work - the second grid didn't show anything. Some debugging and fiddling around, and it turns out that the object returned by DataContext isn't the actual object from my source collection at all. It is an instance of a class called RowTypeDescriptor, which looks deceivingly like the original object, but is in fact an artificial thing that just looks like it has the same properties. Certain properties are missing, and IList implementations like my collection of related objects is among those. Now what?

    There are several possible solutions to this issue. One of them is writing a bit of code in the form of a handler for the CurrentRowChanged event. But I'm going to explore that approach below, so let's focus on the other technique: take advantage of the property This in the XPO base class XPBaseObject, which returns a reference to the object instance. This property gets included in the RowTypeDescriptor, so I can use it to get back to the actual instance of Customer. My working order grid now uses this XAML code:

    <dxg:GridControl Name="orderGrid" AutoPopulateColumns="True"
      DataSource="{Binding ElementName=customerGrid,Path=View.CurrentRowData.DataContext.This.Orders}">
      <dxg:GridControl.View>
        <dxg:GridColumnView />
      </dxg:GridControl.View>
    </dxg:GridControl>

    So far, so good. Now, the DXGrid also supports our fantastic server mode for data binding to XPO. (If you're not familiar with it, it means that the grid queries only the data from the data source that is actually needed in its current view configuration, depending on sorting, filtering, grouping, scrolling, ... very nice feature supported also by our WinForms and ASP.NET datagrids.) This uses a different type of datasource, called XPServerCollectionSource.

    Hooking up my customer grid with this datasource is easy. Just change the line that sets the DataSource property to this:

    customerGrid.DataSource = new XPServerCollectionSource(uow, typeof(Customer));

    Yep, that's all. But there's a problem with the master/detail setup: if the detail grid binds to the Orders collection from the Customer object, the server-mode feature is no longer being used and the entire collection will still be retrieved. Not good. So I'll have to make sure that the binding for the detail grid uses an XPServerCollectionSource as well. This is a use case for the CurrentRowChanged event, as mentioned above. I change my customer grid to this:

    <dxg:GridControl Name="customerGrid" AutoPopulateColumns="True">
      <dxg:GridControl.View>
        <dxg:GridColumnView CurrentRowChanged="GridColumnView_CurrentRowChanged" />
      </dxg:GridControl.View>
    </dxg:GridControl>

    And this is the event handler:

    private void GridColumnView_CurrentRowChanged(object sender,
      DevExpress.Wpf.Grid.CurrentRowChangedEventArgs e) {
      GridColumnView view = (GridColumnView) customerGrid.View;

      var selectedCustomer = (Customer) view.GetRowValue(
        (view.CurrentRowData.DataContext as RowTypeDescriptor).RowHandle.Value);
      orderGrid.DataSource = new XPServerCollectionSource(
        uow, typeof(Order), new BinaryOperator("Customer", selectedCustomer));
    }

    Right, this works. Btw, my demo also includes a little panel that shows the instructions XPO sends to the database - so you can see that it really doesn't request the whole Orders collection at once anymore.

    Finally, there's a way to automate the process of creating an XPServerCollectionSource when the master selection changes. It uses the ability of WPF to integrate a value converter into the data binding process. This converter takes the original collection and creates a corresponding XPServerCollectionSource. Here it is:

    public class CollectionConverter : IValueConverter {
      object IValueConverter.Convert(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture) {
        if (value == null)
          return null;
        var sourceColl = (XPBaseCollection) value;
        return new XPServerCollectionSource(sourceColl.Session,
          sourceColl.GetObjectClassInfo( ).ClassType, sourceColl.Criteria);
      }

     
      object IValueConverter.ConvertBack(object value, Type targetType, object parameter,
        System.Globalization.CultureInfo culture) {
          throw new Exception("The method or operation is not implemented.");
      }
    }

    And here's the XAML code for this automated binding:

    <Page x:Class="DxGrid2.XPServerCollectionSource2Page"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      Title="XPServerCollectionSource2" Height="600" Width="800"
      xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
      xmlns:local="clr-namespace:DxGrid2"
      >
      <Page.Resources>
        <local:CollectionConverter x:Key="collectionConverter" />
      </Page.Resources>
      <DockPanel>
        <StackPanel Orientation="Horizontal">
          <dxg:GridControl Name="customerGrid" AutoPopulateColumns="True">
            <dxg:GridControl.View>
              <dxg:GridColumnView />
            </dxg:GridControl.View>
          </dxg:GridControl>
          <dxg:GridControl Name="orderGrid" AutoPopulateColumns="True"
            DataSource="{Binding ElementName=customerGrid,Path=View.CurrentRowData.DataContext.This.Orders,Converter={StaticResource collectionConverter}}">
            <dxg:GridControl.View>
              <dxg:GridColumnView />
            </dxg:GridControl.View>
          </dxg:GridControl>
        </StackPanel>
      </DockPanel>
    </Page>

    There are several steps necessary to make this possible:

    1. Include the xmlns entry in the Page tag to make the namespace of the application available in XAML.
    2. Create an instance of the CollectionConverter in the page's Resources section.
    3. Add the Converter to the Binding of the orderGrid, referencing the resource.

    As a result, there's no event handler needed anymore. Declarative binding, like it should be in WPF.

    I'm sure that over time we'll make this whole process a bit easier in certain places. We could include IList type properties in the RowTypeDescriptor, or we could find another, more general way of making the original object from the source collection available declaratively. We could automate the server-mode support better, and of course implement master/detail support in the grid internally. Eventually I guess all these things are going to get done, but meanwhile the techniques outlined above provide the functionality quite cleanly.

    Here's the download of the demo application: DxGrid2.zip

  • Getting started with the DevExpress Grid Control for WPF - data binding 1

         

    I've started taking a more in-depth look at our WPF grid control, and I just thought I'd document some of the important steps I'm making for others to follow along. Please feel free to point me towards things that don't seem that easy to do - that's what I'm most interested in!

    For a start, I'm just going to drop a grid control on a form and try to hook it up to data. Since this is WPF, there are of course numerous options for this. For my first test, I have a simple static collection of data in my application, which consists of objects with data about countries. The collection derives from a List<T>.

    On my form, I've got a GridControl inside a DockPanel. I changed the standard layout panel (Grid) to a DockPanel, but otherwise I've left everything as it was after dropping the GridControl on the form. Here's the XAML code:

    <Window x:Class="DxGrid1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="342" Width="534" xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid">
        <DockPanel>
            <dxg:GridControl Name="gridControl1">
                <dxg:GridControl.Columns>
                    <dxg:GridColumn FieldName="Column1" />
                    <dxg:GridColumn FieldName="Column2" />
                </dxg:GridControl.Columns>
                <dxg:GridControl.View>
                    <dxg:GridColumnView />
                </dxg:GridControl.View>
            </dxg:GridControl>
        </DockPanel>
    </Window>

    Now I would like to hook up the grid to my data source. I've got a class called CountryInfoList which just needs to be instantiated. An easy way to do this is of course to create a resource section entry, so I add a namespace line to my Window instantiation:

    xmlns:local="clr-namespace:DxGrid1"

    Then I configure the DataSource property of the grid to bind to the list instance from the resources:

    DataSource="{StaticResource list}"

    I also set the AutoPopulateColumns property to True and I remove the existing two empty columns. This last step is important - if the current column definition collides with the columns that are actually in the data source, the grid currently (that's on the 8.3 version I'm using) throws an exception. (I've registered a bug for this here.)

    At this point the data from my list is already visible in the designer in Visual Studio. My complete XAML looks like this now:

    <Window x:Class="DxGrid1.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:DxGrid1"
        Title="Window1" Height="342" Width="534" xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid">
        <Window.Resources>
            <local:CountryInfoList x:Key="list" />
        </Window.Resources>
        <DockPanel>
            <dxg:GridControl Name="gridControl1" AutoPopulateColumns="True" DataSource="{StaticResource list}">
                <dxg:GridControl.View>
                    <dxg:GridColumnView />
                </dxg:GridControl.View>
            </dxg:GridControl>
        </DockPanel>
    </Window>

    As you see, a hookup to a simple object data source is very easy to do. Of course I could achieve the same result by setting the DataSource property from code - this would allow more flexibility regarding the actual source of my data, since the collection could be constructed more dynamically than the WPF resource system allows. A broad feature set is already supported at this point - sorting, column configuration, grouping.

    Update: Here's the download of the source code for my project.

More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
Chat is one of the many ways you can contact members of the DevExpress Team. We are available Monday-Friday between 8:30am and 5:00pm Pacific Time.
If you need additional product information, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.