Initially I had this code in XAML:
<CollectionViewSource x:Name="cSource">
<CollectionViewSource.Source>
<Binding Source="{StaticResource NameOfXmlDataProvider}" XPath="letter"/>
</CollectionViewSource.Source>
<CollectionViewSource>
But I wanted to keep a binding object in the C# code, to be able to dynamically alter it's xpath. Currently I have this code:
CollectionViewSource viewSource = this.FindResource("cSource") as CollectionViewSource;
Binding binding = new Binding( "Source" );
binding.Source = _xmlDataProvider;
binding.XPath = "/new/path/to/nodes";
BindingOperations.SetBinding( viewSource, CollectionViewSource.SourceProperty, binding );
This compiles and doesn't complain but when called it only leads to an empty list. I can't seem to find related examples in the web - most of them deal with the data providers but I want to change the binding.
- Anybody knows how to fix this?
- Or is there a better way to do this?
- Maybe from retrieving the binding object from the collectionview and changing it?
The problem with the code from the question is the
Source
in the binding. So what works is:If the Constructor is used with a parameter, the parameter is set as the
Path
of the binding. The (additional)XPath
of the binding is then used from that path. So it tried to find "Source" in the XML which lead to an empty selection. The xpath was then working on an empty set of nodes.So it is possible to use the bindings from the code.
Rather than bind to a static resource in the XAML (yuk) or dynamically change the binding (yukkier), bind to things you can change.
If you don't want to go full MVVM, a nice trick is that you can bind your page DataContext to your page's code-behind class by simply naming the
UserControl
element of your page and useElementName
to bind the datacontext to it (the only restriction is that the DataContext binding can't also be on the UserControl (so place it on the first child, like a grid):Now, so long as you have notify properties on your code behind called MyDataProviderProperty and MyDataXPath, you can change them to your heart's content.
You need to use the
SetBinding()
Method of collView. Should be something likecollView.SetBinding(CollectionViewSource.SourceProperty, binding)
Look at http://msdn.microsoft.com/en-us/library/ms752347.aspx for further reference.
Try this:
In the constructor:
Then when you need to change the collection view source:
Then if for instance it is a datagrid, you would call:
Datagrid will now be showing the updated source data.