Since I have been working here at Infragistics, I have been gathering tons of great customer feedback, and have been trying to identify the areas of our WPF product where we can start improving. It became blatantly obvious that the xamDataGrid was way too complicated, and nearly impossible to use without reading the docs, combing the forums, looking at samples, or contacting support. Well, that is just unacceptable. Although our xamDataGrid has more features and is better performing than any of our competitors, it is just too freaking hard to use. So I set out to fix that in our 14.2 release, and fix that I did!
Field Specific Editors
One of the biggest complaints the xamDataGrid had was with how difficult and non-intuitive/discoverable it was to define simple column definitions and set properties for the editors of those columns. For example; let’s say that I want to create a simple column that used a masked text editor and set the mask to some custom string. Sounds like that should be a simple task right? Well, this is what you would have to do in order to achieve that simple scenario.
<igWPF:Field.Settings>
<igWPF:FieldSettings EditorType="{x:Type igWPF:XamMaskedEditor}">
<igWPF:FieldSettings.EditorStyle>
<Style TargetType="{x:Type igWPF:XamMaskedEditor}">
<Setter Property="Mask" Value="########-###" />
</Style>
</igWPF:FieldSettings.EditorStyle>
</igWPF:FieldSettings>
</igWPF:Field.Settings>
</igWPF:Field
So, I have to define a Field and set the Name and Label, then create a FieldSettings object, then set the EditorType of that object. Next, I have to create a style that targets the xamMaskedEditor, set its Mask property via a style setter, and assign the FieldSettings.EditorStyle property. WOW! That’s crazy complicated. What XAML developer on earth would just know that’s what they have to do in order to use a mask for a column? None that I know of. How about you?
Well, we fixed it! Now, we have provided you with field specific editors so that you can define a field based on the editor you require, and then have access to that editor’s properties directly on that field object. So now all you have to do is this:
Now that is so much nicer, and you don’t have to be a rocket scientist to figure it out. Look at all that code that you no longer have to write.
ComboBoxField
But wait, it gets better. You can probably guess that we provide you with field specific editors for all of our supported editors including a ComboBoxField. Yes, that’s right a ComboBoxField! Now this is one of my favorite new field editors. Why do you ask? Well, let’s do a quick review of what you had to do before these new field editors.
First you need to create a ComboBoxItemsProvider as a Resource. But the real issue is trying to bind the ItemsSource to a collection on your DataContext. That’s not so simple. It really only works when you are using your ViewModel as a StaticResource, and honestly, not many people do that. So, it becomes a very confusing and difficult task to even bind your ItemSource at all.
ItemsSource="{Binding StateForDropDowns, Source={StaticResource ViewModel}}"
DisplayMemberPath="Name" ValuePath="StateIdent" />
Then you had to create an EditorStyle, and set the ItemsProvider using a style setter to the ComboBoxItemsProvider:
<igWPF:Field.Settings>
<igWPF:FieldSettings EditorType="{x:Type igWPF:XamComboEditor}">
<igWPF:FieldSettings.EditorStyle>
<Style TargetType="{x:Type igWPF:XamComboEditor}">
<Setter Property="ItemsProvider" Value="{StaticResource stateForDropDownsProvider}" />
</Style>
</igWPF:FieldSettings.EditorStyle>
</igWPF:FieldSettings>
</igWPF:Field.Settings>
</igWPF:Field>
Well, we fixed it! Not only did we fix it, but we improved the ability to data bind field properties as well. If you have ever used the xamDataGrid, then you already know that trying to bind anything on a Field isn’t going to work because those Field objects did not inherit the DataContext. Well, now you can. Now all you have to do is this:
ItemsSource="{Binding DataContext.StateForDropDowns, RelativeSource={RelativeSource Self}}"
DisplayMemberPath="Name" ValuePath="StateIdent" />
FieldBinding
While that is nice and all, it is still too much code to write to create the binding. So, we went ahead and simplified that even more by providing a custom binding markup extension called FieldBinding so that you can do this:
ItemsSource="{igWPF:FieldBinding StateForDropDowns}"
DisplayMemberPath="Name" ValuePath="StateIdent" />
Now that is looking much better. This new FieldBinding markup extension is to be used anytime you want to data bind a property of a field to the DataContext of the xamDataGrid. So for example, you can also do something like this:
But why limit it to just fields? We can use this for FieldSetting too. So we can even do something like this:
AllowAddNew="{igWPF:FieldBinding IsAddNewRecordAllowed}"
AllowDelete="{igWPF:FieldBinding IsDeleteAllowed}"/>
Cell Bindings
Now, you may be thinking to yourself “hey Brian, this is freaking amazing like everything else you do, but what if I want to data bind a property from the underlying data bound item to a property on the editor on a row-by-row basis?”. My answer to you is No Problemo! We also introduced the concept of what’s called a CellBinding. You can create any number of CellBindings to create a binding between a property of the editor to the underlying data item, AND to any property of the CellValuePresenter as well.
Prepare to have your mind blown…
<igWPF:TextField.CellBindings>
<igWPF:CellBinding Property="Foreground"
Target="CellValuePresenter"
Binding="{Binding Path=DataItem.Color, Converter={StaticResource ColorToBrushConverter}}"/>
<igWPF:CellBinding Property="IsEnabled"
Target="Editor"
Binding="{Binding Path=DataItem.IsAvailable}" />
</igWPF:TextField.CellBindings>
</igWPF:TextField>
As you can probably see, we are creating a binding for the Foreground of the CellValuePresenter and the IsEnabled property of the Editor to different properties on the underlying data item. Now that is just sick!
Template Fields
So, right about now you are running down the street cheering “Brian for President”, but wait just a minute, because I’m not done yet! Have you ever needed to use a custom control as an editor in a column? I know I have. Before, it was a major pain in the butt, and honestly, I couldn’t even get it to work. That’s how bad it was.
Well, we fixed it! We have now added a new TemplateField so that you can now provide your very own custom control for both the display and edit states of a cell. So, let’s say you want to use the xamColorPicker as an editor in the xamDataGrid. Well, we don’t have one built in, so you would be responsible for writing all the custom code to make it work. I’m not even going to add the code to do that because it was so complicated. Instead, we will jump right into how you do it now with the new TemplateField.
<igWPF:TemplateField.DisplayTemplate>
<DataTemplate>
<Rectangle Width="130" Height="20"
Fill="{Binding Path=(igWPF:TemplateEditor.Editor).Value,
RelativeSource={RelativeSource Self}}"/>
</DataTemplate>
</igWPF:TemplateField.DisplayTemplate>
<igWPF:TemplateField.EditTemplate>
<DataTemplate>
<ig:XamColorPicker Width="130" Height="20"
SelectedColor="{Binding Path=(igWPF:TemplateEditor.Editor).Value,
RelativeSource={RelativeSource Self},
UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</DataTemplate>
</igWPF:TemplateField.EditTemplate>
</igWPF:TemplateField>
As you can see, we are providing a Rectangle to represent our DisplayTemplate, and the xamColorPicker as the EditTemplate. As you can see, the binding syntax looks a little complicated. So, we decided to make that a little easier for you as well. We added a a new binding markup extension called TemplateEditorValueBinding which simplifies all of that messy binding syntactical sugar. So you can simply write:
<igWPF:TemplateField.DisplayTemplate>
<DataTemplate>
<Rectangle Width="130" Height="20" Fill="{igWPF:TemplateEditorValueBinding}"/>
</DataTemplate>
</igWPF:TemplateField.DisplayTemplate>
<igWPF:TemplateField.EditTemplate>
<DataTemplate>
<ig:XamColorPicker Width="130" Height="20" SelectedColor="{igWPF:TemplateEditorValueBinding}" />
</DataTemplate>
</igWPF:TemplateField.EditTemplate>
</igWPF:TemplateField>
API Improvements
The last thing I want to mention is the improvements we made to the field API. We tried to identify the most commonly used properties that are exposed off of the FieldSettings class and surfaced them on the Field level. What do this mean for you? It means fewer lines of code.
So instead of having to do write this:
<igWPF:Field.Settings>
<igWPF:FieldSettings AllowEdit="False"
AllowFixing="Near"
AllowGroupBy="False" />
</igWPF:Field.Settings>
</igWPF:Field>
You can remove the FieldSettings object completely, and just do it like this:
Summary
As you can see, we have made a ton of improvements to the xamDataGrid, and all of these features are available to you now in the 14.2 release of the Infragistics WPF controls. My job here at Infragistics is to improve the Infragistics WPF controls to make your job easier. If you have complaints, I want to know about it. If you have feature requests, I want to know about them. If you have positive comments, those are welcome as well. The point I am trying to make is that you need to let me know what you think, good or bad. You can do that in a number of ways. First you can submit your feature requests to the Infragistics Product Ideas website. If you don’t submit the idea, it will never get considered for implementation. You can follow and contact me directly on Twitter at @brianlagunas. You can even leave a comment on this post. Now you have no excuse of why you can’t provide feedback.
Well, the xamDataGrid is something I spend a lot of time with which makes my wife jealous. The changes you have made will give me time back to distribute elsewhere!!!! thanks Brian. Excellent post, excellent tools from Infragistics.
I’m happy that these changes will help you save time, and make the control much easier to use. Now you can use your newly discovered free time with your wife. Tell your wife I said “you’re welcome” :0)
😉 Yes, she said “thank you xx”
Great post Brian – really clear and a great explanation of the new functionality…you mention TemplateEditorValueBinding as a way to get the value when using a TemplateField. How can I get to the row of data? Getting the value works fine, but I need to bind a property of a TemplateField to the value of another cell in the row. Reason for this is that I have a TemplateField that I need to display using a different control depending on the value in another cell. Hopefully this makes some sense.
Thanks,
David
For now, you could try using the CellBindings. We are going to add support for a TemplateSelector in the next version to make switching out controls much easier for you.
Thanks Brian. Had a bit of a try and not really getting what I needed…going to wait for the TemplateSelector support