How do I sublass a control along with its attached properties? - silverlight

I am trying to subclass System.Windows.Controls.DataGrid in order to add special commands to which a view model can bind. How do I do this and still have the Columns attached property? Do I have to declare it against my new type in order to use it?

Columns is not an attached property.. you should use it the same way you always do, just replace DataGrid with your-control-name:
<my:MyDataGrid>
<my:MyDataGrid.Columns>
<!-- Columns goes here --->
</my:MyDataGrid.Columns>
</my:MyDataGrid>

Related

WPF datagrid - flexible binding for group headers

I have a wpf datagrid with grouped rows, implemented using a CollectionViewSource. It appears the group header templates bind directly to CollectionViewGroup objects, but for some reason these aren't very accessible inside the CVS. You give the CollectionViewSource the group names, and it handles generating the CVG's behind the scenes. This makes things difficult if you want the group header styles to bind to something other than what few properties the CVG's expose, like Name and ItemCount.
Basically, I want every group to have a Status property, probably to be visually indicated by the group header background color. This Status can change, so somehow the header will have to detect propertychanged notifications. But since CollectionViewGroup does not have a Status property, and I cannot supply my own CVGs to the CollectionViewSource, I've no idea how to do this simple task.
I figured it out eventually. The Name property of CollectionViewGroup is an object, so you can create a group view model of desired properties, then give that as the Name when adding group descriptions to the CollectionViewSource. And then in the xaml just do nested binding to Name.whatever for the group header controls.
I set it up like so (vb.net to follow):
Me.BindedCV = New Data.CollectionViewSource
Me.BindedCV.GroupDescriptions.Add(New Data.PropertyGroupDescription("ProductGroup"))
This means all rows (more specifically, the viewmodels that the rows are binded to) will be grouped according to a property called ProductGroup. Now I add my own group objects to the CollectionView group descriptions:
Dim pg = New ProductGroupVM(pd.Index)
Me._ProductGroupVMs.Add(pg)
Me.BindedCV.GroupDescriptions(0).GroupNames.Add(pg)
So by adding pg to the GroupNames collection means it can now be referenced and binded to in the xaml group header styling - it is the Name object. Note that I also added pg to a second private collection I created called _ProductGroupVMs. This is a bit hackish, but that way I can keep a reference to all my group objects - when I create the row viewmodels, they will have a ProductGroup property, and ProductGroup needs to point to the right pg in order for them to be grouped correctly. There might be cleaner ways to do it but that's the route I went.

Is this kind of grouping supported for Silverlight 4 DataGrid?

Is this kind of grouping possible for Silverlight DataGrids?
The first three rows of the first column are combined into one block because their data are the same.
No, the default Silverlight datagrid control does not support this kind of grouping, however you can achive a similar result using template columns:
First you should create a Class that would contain the grouped data, something like this:
MySourceClass
{
string GroupColumn {get;set;}
List<object> GroupedColumn1 {get;set;}
}
Then bind your DataGrid to a collection of MySourceClass (or whatever name you call it), and create a TextColumn for Column1, and a TemplateColumn for Column2 with a ListBox or similar, and bind the source of the Listbox to the GroupedColumn property.
You might have to thinker a bit with the styles, but i'm pretty sure you can acomplish a solid look with this aproach.
EDIT:
Alternatively you could use the default DataGrid grouping, her's a good example for it:
http://www.codeproject.com/Articles/134340/Grouping-Records-in-Silverlight-DataGrid-using-Pag

Binding an ItemsControl to a derived type with XAML

Is it possible to bind an ItemsControl to a derived type (from an abstract base) using XAML only?
I have a Class called "RouteStop". Within "RouteStop", there is a collection of a class "Payment".
Payment is an abstract class with derived classes ExpectedPayment and ActualPayment.
I have an ItemsControl bound to "RouteStops". For each row, there are zero-to-many "ExpectedPayment" and zero-to-many "ActualPayment" records. I want to display the two derived classes in side-by-side ItemsControls for each RouteStop.
I understand you can use Linq to retrieve the derived type. As in...
context.Payments.OfType<ExpectedPayment>()
But I'd prefer not to set this using code on a row by row basis. Is there a way to do this declaratively with XAML? Do I have to modify the SSDL to create a way to access the derived types?
And if this is not possible, what would be a best practice?
Thank you in advance for any time spent on this.

Setting a converter on a GroupDescriptor in Silverlight 4

I have a read-only datagrid bound to a domain data source. The data that I'm binding to has an ID property that I'm resolving on the grid through a converter (a simple int -> string mapping). The domain data source also has a GroupDescriptor on it, and this works, except I'm grouping by that column which has a converter on it.
Unfortunately the group header doesn't use the Converter and therefore just displays the ID, which is not desirable. I can replace the control template for the group header and explicitly use a converter on the template, but this is obviously not an ideal solution as I'm hard-coding the template to the converter.
Is there a way to use a converter on a group descriptor?
i found out that if you create a PropertyGroupDescription in code, it allows you to supply an IValueConverter in the constructor, so this would appear to be an answer.

Freezing a DataGridTextColumn in WPF

I would like to freeze a DataGridTextColumn in WPF but it looks like there is not a property for that in that class specifically. However, looking at the source for the WPFToolkit, there is a IsFrozen in DataGridColumn which is the parent of DataGridBoundColumn, which is the parent of DataGridTextColumn. So...why isn't that property available?
I believe this property is not available because it's a read only. Since frozen columns are always the leftmost columns in display order you can use datagrid's FrozenColumnCount property to freeze whatever number of columns you need. You can set it up in xaml or chage it in you code. See documentation for more details here

Resources