Search code examples
c#wpfxamldata-bindingcollectionview

How do I change the binding of a CollectionView.Source?


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?

Solution

  • Rather than bind to a static resource in the XAML (yuk) or dynamically change the binding (yukkier), bind to things you can change.

    <CollectionViewSource x:Name="cSource">
      <CollectionViewSource.Source>
        <Binding Source="{Binding MyDataProviderProperty}" XPath="{Binding MyDataXPathProperty}"/>
      </CollectionViewSource.Source>
    <CollectionViewSource>
    

    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 use ElementName 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):

    <UserControl x:Class="BindingTests.BindingToSelfExample"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="400" x:Name="MyViewClass">
        <Grid x:Name="LayoutRoot" Background="White" DataContext="{Binding ElementName=MyViewClass}">
            <TextBlock Text="{Binding SomePropertyOfTheCodeBehind}" Width="100" Height="20"/>
        </Grid>
    </UserControl>
    

    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.