<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: WPF&#8217;s CollectionViewSource</title>
	<atom:link href="http://bea.stollnitz.com/blog/?feed=rss2&#038;p=387" rel="self" type="application/rss+xml" />
	<link>http://bea.stollnitz.com/blog/?p=387</link>
	<description>on Silverlight and WPF</description>
	<lastBuildDate>Mon, 02 Aug 2010 17:57:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Catherine</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-211887</link>
		<dc:creator>Catherine</dc:creator>
		<pubDate>Wed, 30 Jun 2010 08:29:11 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-211887</guid>
		<description>Oh. I see. The datagrid binds to FirstName and Lastname the others to FullName which is a calculated property in the Employee partial class (Employee is Linq to SQL). When I bind to FirstName, it works. Spent all day on it and couldn&#039;t see it until I posted here.</description>
		<content:encoded><![CDATA[<p>Oh. I see. The datagrid binds to FirstName and Lastname the others to FullName which is a calculated property in the Employee partial class (Employee is Linq to SQL). When I bind to FirstName, it works. Spent all day on it and couldn&#8217;t see it until I posted here.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kevin</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-193445</link>
		<dc:creator>Kevin</dc:creator>
		<pubDate>Wed, 10 Mar 2010 18:47:21 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-193445</guid>
		<description>Hey Bea,

As a matter of fact, I am using WPF (sorry for not pointing that out). I didn&#039;t realize there was a difference, so I didn&#039;t bother checking if it worked, since I read it didn&#039;t for silverlight. Thanks for point that out!

The only piece of the puzzle that&#039;s missing now is the blend issue.

Kevin</description>
		<content:encoded><![CDATA[<p>Hey Bea,</p>
<p>As a matter of fact, I am using WPF (sorry for not pointing that out). I didn&#8217;t realize there was a difference, so I didn&#8217;t bother checking if it worked, since I read it didn&#8217;t for silverlight. Thanks for point that out!</p>
<p>The only piece of the puzzle that&#8217;s missing now is the blend issue.</p>
<p>Kevin</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-193427</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Wed, 10 Mar 2010 17:23:50 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-193427</guid>
		<description>Hi Kevin,

I&#039;m assuming you&#039;re using Silverlight. If you were using WPF, you would be able to place the two CollectionViewSources in the resources section of your view, and they would inherit the data context as expected. In Silverlight this doesn&#039;t happen though. The Silverlight workaround you point out in the link is good. It&#039;s unfortunate that it can&#039;t be done in XAML, but it&#039;s really not that much extra code. At some point, I expect to see the WPF DataContext inheritance in Silverlight too.

Sorry I can&#039;t help you with the Blend question.

Bea</description>
		<content:encoded><![CDATA[<p>Hi Kevin,</p>
<p>I&#8217;m assuming you&#8217;re using Silverlight. If you were using WPF, you would be able to place the two CollectionViewSources in the resources section of your view, and they would inherit the data context as expected. In Silverlight this doesn&#8217;t happen though. The Silverlight workaround you point out in the link is good. It&#8217;s unfortunate that it can&#8217;t be done in XAML, but it&#8217;s really not that much extra code. At some point, I expect to see the WPF DataContext inheritance in Silverlight too.</p>
<p>Sorry I can&#8217;t help you with the Blend question.</p>
<p>Bea</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Kevin</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-193351</link>
		<dc:creator>Kevin</dc:creator>
		<pubDate>Wed, 10 Mar 2010 10:52:42 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-193351</guid>
		<description>Hi Bea,

I thought this might work for the scenario I&#039;m using:

Suppose I have one ObservableCollection. I want to show the items of this collection in two different locations, each with a different sorting. The way to go, I presume, would be to create a CollectionViewSource in each of the two different locations, with different sorting specified in xaml. 

However, two problems arise:

1) As featured here http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource.aspx , the CollectionViewSource is defined in the resources section and its source is set to a locally defined resource/observableCollection. However, what if I&#039;m working with MVVM? I would then like to bind the Source property of the CollectionViewSource to an ObservableCollection in my view model, which apparently can&#039;t be done, since the CollectionViewSource has no access to the datacontext of the window/control it&#039;s defined in (whose datacontext would be the view model). A possible solution would be this: http://www.silverlightplayground.org/post/2009/07/18/Use-CollectionViewSource-effectively-in-MVVM-applications.aspx The CollectionViewSource gets created in the view model and sorting gets applied there. You would then bind your itemscontrol.itemssource to  the CollectionViewSource.View in the view model. However, you would lose the advantage of doing it all in XAML.
2) How is this all supposed to work in Blend? Ideally I would like the programmer to be able to write a viewmodel, which the user interface maker could use in Blend. However, when I&#039;ve created the CollectionViewSource in the view model (as in the above scenario), it looks like Blend can&#039;t resolve the object type when setting the ItemsSource of an ItemsControl to the view model&#039;s CollectionViewSource.View. Which is understandable, since the CollectionViewSource.view isn&#039;t typed.

Any ideas on this?</description>
		<content:encoded><![CDATA[<p>Hi Bea,</p>
<p>I thought this might work for the scenario I&#8217;m using:</p>
<p>Suppose I have one ObservableCollection. I want to show the items of this collection in two different locations, each with a different sorting. The way to go, I presume, would be to create a CollectionViewSource in each of the two different locations, with different sorting specified in xaml. </p>
<p>However, two problems arise:</p>
<p>1) As featured here <a href="http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource.aspx</a> , the CollectionViewSource is defined in the resources section and its source is set to a locally defined resource/observableCollection. However, what if I&#8217;m working with MVVM? I would then like to bind the Source property of the CollectionViewSource to an ObservableCollection in my view model, which apparently can&#8217;t be done, since the CollectionViewSource has no access to the datacontext of the window/control it&#8217;s defined in (whose datacontext would be the view model). A possible solution would be this: <a href="http://www.silverlightplayground.org/post/2009/07/18/Use-CollectionViewSource-effectively-in-MVVM-applications.aspx" rel="nofollow">http://www.silverlightplayground.org/post/2009/07/18/Use-CollectionViewSource-effectively-in-MVVM-applications.aspx</a> The CollectionViewSource gets created in the view model and sorting gets applied there. You would then bind your itemscontrol.itemssource to  the CollectionViewSource.View in the view model. However, you would lose the advantage of doing it all in XAML.<br />
2) How is this all supposed to work in Blend? Ideally I would like the programmer to be able to write a viewmodel, which the user interface maker could use in Blend. However, when I&#8217;ve created the CollectionViewSource in the view model (as in the above scenario), it looks like Blend can&#8217;t resolve the object type when setting the ItemsSource of an ItemsControl to the view model&#8217;s CollectionViewSource.View. Which is understandable, since the CollectionViewSource.view isn&#8217;t typed.</p>
<p>Any ideas on this?</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-193289</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Wed, 10 Mar 2010 06:15:10 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-193289</guid>
		<description>Thanks for posting your code Owen.
I&#039;ll actually be discussing a scenario similar to this one in my next blog post, so stay tuned.

Bea</description>
		<content:encoded><![CDATA[<p>Thanks for posting your code Owen.<br />
I&#8217;ll actually be discussing a scenario similar to this one in my next blog post, so stay tuned.</p>
<p>Bea</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Beginner</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-192129</link>
		<dc:creator>Beginner</dc:creator>
		<pubDate>Wed, 03 Mar 2010 11:22:30 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-192129</guid>
		<description>I&#039;ve found what was looking for! :-)
Thanks for detailed explanations and working sample code!

Your blog is amazing and very very usefull!
Keep shining! :-)</description>
		<content:encoded><![CDATA[<p>I&#8217;ve found what was looking for! :-)<br />
Thanks for detailed explanations and working sample code!</p>
<p>Your blog is amazing and very very usefull!<br />
Keep shining! :-)</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Owen</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-187815</link>
		<dc:creator>Owen</dc:creator>
		<pubDate>Tue, 09 Feb 2010 21:06:26 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-187815</guid>
		<description>Hi John,
  I&#039;ve actually gotten this working the way one would expect: items at different levels filter out (based on a text search in my case) unless children pass that same filter.  I&#039;ll warn you that this solution is not pretty.  It is code-concise but has the major drawback of regenerating the containers (ie reapplying the template) every time the filter text changes.



    
        
            
        
    


public class CollectionViewConverter : IValueConverter, INotifyPropertyChanged
    {
        private string _filterText = string.Empty;

        public string FilterText
        {
            get
            {
                return _filterText;
            }
            set
            {
                _filterText = value;
                foreach (CollectionViewSource cvs in _sources.Values)
                {
                    cvs.View.Refresh();
                }
                PropertyChangedEventHandler localHandler = PropertyChanged;
                if (localHandler != null)
                {
                    localHandler(this, new PropertyChangedEventArgs(&quot;FilterText&quot;));
                }
            }
        }

        private void OnFilter(object sender, FilterEventArgs e)
        {
            e.Accepted = (e.Item as IOutput).Name.Contains(FilterText) &#124;&#124; !_sources[e.Item].View.IsEmpty;
        }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region IValueConverter Members

        private Dictionary _sources = new Dictionary();

        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (!_sources.ContainsKey(value))
            {
                CollectionViewSource childrenCvs = new CollectionViewSource();
                childrenCvs.Source = value;
                childrenCvs.Filter += OnFilter;
                _sources.Add(value, childrenCvs);
            }
            return _sources[value].View;
        }

        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        #endregion
    }

If you need top-level filtering as well you&#039;ll need to hook up an identical filter method at that level (I have that sitting in the MainWIndow and use
e.Accepted = (e.Item as IOutput).Name.Contains(_filterBox.Text) &#124;&#124; !((_treeView.ItemContainerGenerator.ContainerFromItem(e.Item) as Telerik.Windows.Controls.ItemsControl).ItemsSource as ICollectionView).IsEmpty;</description>
		<content:encoded><![CDATA[<p>Hi John,<br />
  I&#8217;ve actually gotten this working the way one would expect: items at different levels filter out (based on a text search in my case) unless children pass that same filter.  I&#8217;ll warn you that this solution is not pretty.  It is code-concise but has the major drawback of regenerating the containers (ie reapplying the template) every time the filter text changes.</p>
<p>public class CollectionViewConverter : IValueConverter, INotifyPropertyChanged<br />
    {<br />
        private string _filterText = string.Empty;</p>
<p>        public string FilterText<br />
        {<br />
            get<br />
            {<br />
                return _filterText;<br />
            }<br />
            set<br />
            {<br />
                _filterText = value;<br />
                foreach (CollectionViewSource cvs in _sources.Values)<br />
                {<br />
                    cvs.View.Refresh();<br />
                }<br />
                PropertyChangedEventHandler localHandler = PropertyChanged;<br />
                if (localHandler != null)<br />
                {<br />
                    localHandler(this, new PropertyChangedEventArgs(&#8220;FilterText&#8221;));<br />
                }<br />
            }<br />
        }</p>
<p>        private void OnFilter(object sender, FilterEventArgs e)<br />
        {<br />
            e.Accepted = (e.Item as IOutput).Name.Contains(FilterText) || !_sources[e.Item].View.IsEmpty;<br />
        }</p>
<p>        #region INotifyPropertyChanged Members</p>
<p>        public event PropertyChangedEventHandler PropertyChanged;</p>
<p>        #endregion</p>
<p>        #region IValueConverter Members</p>
<p>        private Dictionary _sources = new Dictionary();</p>
<p>        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)<br />
        {<br />
            if (!_sources.ContainsKey(value))<br />
            {<br />
                CollectionViewSource childrenCvs = new CollectionViewSource();<br />
                childrenCvs.Source = value;<br />
                childrenCvs.Filter += OnFilter;<br />
                _sources.Add(value, childrenCvs);<br />
            }<br />
            return _sources[value].View;<br />
        }</p>
<p>        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)<br />
        {<br />
            throw new NotSupportedException();<br />
        }</p>
<p>        #endregion<br />
    }</p>
<p>If you need top-level filtering as well you&#8217;ll need to hook up an identical filter method at that level (I have that sitting in the MainWIndow and use<br />
e.Accepted = (e.Item as IOutput).Name.Contains(_filterBox.Text) || !((_treeView.ItemContainerGenerator.ContainerFromItem(e.Item) as Telerik.Windows.Controls.ItemsControl).ItemsSource as ICollectionView).IsEmpty;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: John</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-185562</link>
		<dc:creator>John</dc:creator>
		<pubDate>Sun, 24 Jan 2010 14:49:39 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-185562</guid>
		<description>Wow - thank for a truly comprehensive reply.

For some reason I&#039;d never considered using DataTemplate resources (as per option 2) although now you explain it I can understand why that doesn&#039;t work (and I&#039;ll remember that point for future).

Using a converter in the ItemsSource binding seems like a good idea and one that will work for me I think - The sample project is a great help, thank you.

I&#039;d been using Linq up to now to populate a secondary collection, which works but feel like a rather heavy solution.

Anyway, thanks again for taking the time to reply in such detail.  It has really helped fill in the gaps for me.

Best regards

John</description>
		<content:encoded><![CDATA[<p>Wow &#8211; thank for a truly comprehensive reply.</p>
<p>For some reason I&#8217;d never considered using DataTemplate resources (as per option 2) although now you explain it I can understand why that doesn&#8217;t work (and I&#8217;ll remember that point for future).</p>
<p>Using a converter in the ItemsSource binding seems like a good idea and one that will work for me I think &#8211; The sample project is a great help, thank you.</p>
<p>I&#8217;d been using Linq up to now to populate a secondary collection, which works but feel like a rather heavy solution.</p>
<p>Anyway, thanks again for taking the time to reply in such detail.  It has really helped fill in the gaps for me.</p>
<p>Best regards</p>
<p>John</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-185288</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Fri, 22 Jan 2010 19:03:33 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-185288</guid>
		<description>Hi John,
See above for a reply. 
Bea</description>
		<content:encoded><![CDATA[<p>Hi John,<br />
See above for a reply.<br />
Bea</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Bea</title>
		<link>http://bea.stollnitz.com/blog/?p=387&#038;cpage=1#comment-185287</link>
		<dc:creator>Bea</dc:creator>
		<pubDate>Fri, 22 Jan 2010 18:51:59 +0000</pubDate>
		<guid isPermaLink="false">http://bea.stollnitz.com/blog/?p=387#comment-185287</guid>
		<description>Hi John,

WPF doesn&#039;t have good intuitive support for filtering at different levels of the hierarchy, unfortunately. This scenario was discussed a few times when I was still on the team, but we never ended up adding better support for it.

To filter at different levels, you need to have a filter method for each of those levels. All collections of a level need to have that filter specified in their view. At first sight it seems like this would be easy to achieve through XAML, by adding a CollectionViewSource with a Filter to each HierarchicalDataTemplate, but it&#039;s not as easy as it seems. I have seen people try three approaches to this problem, all of which don&#039;t work. (Excuse me for any typos in the code/XAML below, as I&#039;m just typing it on the fly, not compiling it.)

1. Add the CollectionViewSources for all levels to the window&#039;s resources, and bind the ItemsSource of each HierarchicalDataTemplate to the corresponding CollectionViewSource:

(This assume the DataContext for the window is an ObservableCollection of Mountain.)

&lt;Window.Resources&gt;
&lt;CollectionViewSource x:Key=&quot;MountainsCVS&quot; Source=&quot;{Binding}&quot; Filter=&quot;FilterMountain&quot; /&gt;
&lt;CollectionViewSource x:Key=&quot;LiftsCVS&quot; Source=&quot;{Binding Lifts}&quot; Filter=&quot;FilterLift&quot; /&gt;
&lt;CollectionViewSource x:Key=&quot;RunsCVS&quot; Source=&quot;{Binding Runs}&quot; Filter=&quot;FilterRun&quot; /&gt;

&lt;HierarchicalDataTemplate DataType=&quot;{x:Type local:Mountain}&quot; ItemsSource=&quot;{Binding Source={StaticResource FilterLift}}&quot;&gt;
&lt;TextBlock Text=&quot;{Binding Name}&quot; /&gt;
&lt;/HierarchicalDataTemplate&gt;

&lt;HierarchicalDataTemplate DataType=&quot;{x:Type local:Lift}&quot; ItemsSource=&quot;{Binding Source={StaticResource FilterRuns}}&quot;&gt;
&lt;TextBlock Text=&quot;{Binding Name}&quot; /&gt;
&lt;/HierarchicalDataTemplate&gt;
&lt;/Window.Resources&gt;

This doesn&#039;t work because all CollectionViewSources have the same data context - the collection of Mountain. Their data context doesn&#039;t change depending on where they&#039;re used.

2. Add the CollectionViewSource to the resources of the HierarchicalDataTemplate:

&lt;HierarchicalDataTemplate DataType=&quot;{x:Type local:Mountain}&quot;&gt;
&lt;HierarchicalDataTemplate.Resources&gt;
&lt;CollectionViewSource x:Key=&quot;LiftsCVS&quot; Source=&quot;{Binding Lifts}&quot; Filter=&quot;FilterLift&quot; /&gt;
&lt;/HierarchicalDataTemplate.Resources&gt;
&lt;HierarchicalDataTemplate.ItemsSource&gt;
&lt;Binding Source=&quot;{StaticResource LiftsCVS}&quot; /&gt;
&lt;/HierarchicalDataTemplate.ItemsSource&gt;
&lt;TextBlock Text=&quot;{Binding Name}&quot; /&gt;
&lt;/HierarchicalDataTemplate&gt;

The data context for the template is a specific Mountain instance, which leads people to believe that the CollectionViewSource would pick up the rigth data context. However, this doesn&#039;t work because, although the each instance of the HierarchicalDataTemplate has its data context set to a specific Mountain, the resources section does not inherit that data context (it has no data context). This happens because the resources added there are shared across all instantiations of the template. So this solution doesn&#039;t work either.

3. Add the CollectionViewSource directly in the ItemsSource of the HierarchicalDataTemplate:

&lt;HierarchicalDataTemplate DataType=&quot;{x:Type local:Mountain}&quot;&gt;
&lt;HierarchicalDataTemplate.ItemsSource&gt;
&lt;Binding&gt;
&lt;Binding.Source&gt;
&lt;CollectionViewSource Source=&quot;{Binding Lifts}&quot; Filter=&quot;FilterLift&quot; /&gt;
&lt;/Binding.Source&gt;
&lt;/Binding&gt;
&lt;/HierarchicalDataTemplate.ItemsSource&gt;
&lt;TextBlock Text=&quot;{Binding Name}&quot; /&gt;
&lt;/HierarchicalDataTemplate&gt;

In this case you end up with a nested binding, which also doesn&#039;t pick up the data context as may be expected.

So, what can you do instead? 

If your data doesn&#039;t change, you can use a converter to filter the data at first load. You can take a look at a simple &lt;a href=&quot;http://bea.stollnitz.com/BlogComments/49FilteringHierarchy.zip&quot; rel=&quot;nofollow&quot;&gt;project&lt;/a&gt; that uses a converter for this purpose. The concept is quite simple - the converter gets added in the ItemsSource Binding, and the filter logic goes in the converter implementation.

&lt;HierarchicalDataTemplate DataType=&quot;{x:Type local:Lift}&quot; ItemsSource=&quot;{Binding Path=Runs, Converter={StaticResource FilterRunsConverter}}&quot;&gt;
&lt;TextBlock Text=&quot;{Binding Name}&quot; /&gt;
&lt;/HierarchicalDataTemplate&gt;

If your data changes, you can write code that ensures that all TreeViewItems are data bound to views that wrap their original collections with the Filter property set. You may also consider adding filtering on the data logic side of the app, instead of using the client-side built-in filtering capabilities of WPF.

In addition, there may be other creative and tricky ways of adding CollectionViewSources with the Filter method directly in XAML, and if you find an elegant way of doing it, please let me know.

Hope this helps.
Bea</description>
		<content:encoded><![CDATA[<p>Hi John,</p>
<p>WPF doesn&#8217;t have good intuitive support for filtering at different levels of the hierarchy, unfortunately. This scenario was discussed a few times when I was still on the team, but we never ended up adding better support for it.</p>
<p>To filter at different levels, you need to have a filter method for each of those levels. All collections of a level need to have that filter specified in their view. At first sight it seems like this would be easy to achieve through XAML, by adding a CollectionViewSource with a Filter to each HierarchicalDataTemplate, but it&#8217;s not as easy as it seems. I have seen people try three approaches to this problem, all of which don&#8217;t work. (Excuse me for any typos in the code/XAML below, as I&#8217;m just typing it on the fly, not compiling it.)</p>
<p>1. Add the CollectionViewSources for all levels to the window&#8217;s resources, and bind the ItemsSource of each HierarchicalDataTemplate to the corresponding CollectionViewSource:</p>
<p>(This assume the DataContext for the window is an ObservableCollection of Mountain.)</p>
<p>&lt;Window.Resources&gt;<br />
&lt;CollectionViewSource x:Key=&#8221;MountainsCVS&#8221; Source=&#8221;{Binding}&#8221; Filter=&#8221;FilterMountain&#8221; /&gt;<br />
&lt;CollectionViewSource x:Key=&#8221;LiftsCVS&#8221; Source=&#8221;{Binding Lifts}&#8221; Filter=&#8221;FilterLift&#8221; /&gt;<br />
&lt;CollectionViewSource x:Key=&#8221;RunsCVS&#8221; Source=&#8221;{Binding Runs}&#8221; Filter=&#8221;FilterRun&#8221; /&gt;</p>
<p>&lt;HierarchicalDataTemplate DataType=&#8221;{x:Type local:Mountain}&#8221; ItemsSource=&#8221;{Binding Source={StaticResource FilterLift}}&#8221;&gt;<br />
&lt;TextBlock Text=&#8221;{Binding Name}&#8221; /&gt;<br />
&lt;/HierarchicalDataTemplate&gt;</p>
<p>&lt;HierarchicalDataTemplate DataType=&#8221;{x:Type local:Lift}&#8221; ItemsSource=&#8221;{Binding Source={StaticResource FilterRuns}}&#8221;&gt;<br />
&lt;TextBlock Text=&#8221;{Binding Name}&#8221; /&gt;<br />
&lt;/HierarchicalDataTemplate&gt;<br />
&lt;/Window.Resources&gt;</p>
<p>This doesn&#8217;t work because all CollectionViewSources have the same data context &#8211; the collection of Mountain. Their data context doesn&#8217;t change depending on where they&#8217;re used.</p>
<p>2. Add the CollectionViewSource to the resources of the HierarchicalDataTemplate:</p>
<p>&lt;HierarchicalDataTemplate DataType=&#8221;{x:Type local:Mountain}&#8221;&gt;<br />
&lt;HierarchicalDataTemplate.Resources&gt;<br />
&lt;CollectionViewSource x:Key=&#8221;LiftsCVS&#8221; Source=&#8221;{Binding Lifts}&#8221; Filter=&#8221;FilterLift&#8221; /&gt;<br />
&lt;/HierarchicalDataTemplate.Resources&gt;<br />
&lt;HierarchicalDataTemplate.ItemsSource&gt;<br />
&lt;Binding Source=&#8221;{StaticResource LiftsCVS}&#8221; /&gt;<br />
&lt;/HierarchicalDataTemplate.ItemsSource&gt;<br />
&lt;TextBlock Text=&#8221;{Binding Name}&#8221; /&gt;<br />
&lt;/HierarchicalDataTemplate&gt;</p>
<p>The data context for the template is a specific Mountain instance, which leads people to believe that the CollectionViewSource would pick up the rigth data context. However, this doesn&#8217;t work because, although the each instance of the HierarchicalDataTemplate has its data context set to a specific Mountain, the resources section does not inherit that data context (it has no data context). This happens because the resources added there are shared across all instantiations of the template. So this solution doesn&#8217;t work either.</p>
<p>3. Add the CollectionViewSource directly in the ItemsSource of the HierarchicalDataTemplate:</p>
<p>&lt;HierarchicalDataTemplate DataType=&#8221;{x:Type local:Mountain}&#8221;&gt;<br />
&lt;HierarchicalDataTemplate.ItemsSource&gt;<br />
&lt;Binding&gt;<br />
&lt;Binding.Source&gt;<br />
&lt;CollectionViewSource Source=&#8221;{Binding Lifts}&#8221; Filter=&#8221;FilterLift&#8221; /&gt;<br />
&lt;/Binding.Source&gt;<br />
&lt;/Binding&gt;<br />
&lt;/HierarchicalDataTemplate.ItemsSource&gt;<br />
&lt;TextBlock Text=&#8221;{Binding Name}&#8221; /&gt;<br />
&lt;/HierarchicalDataTemplate&gt;</p>
<p>In this case you end up with a nested binding, which also doesn&#8217;t pick up the data context as may be expected.</p>
<p>So, what can you do instead? </p>
<p>If your data doesn&#8217;t change, you can use a converter to filter the data at first load. You can take a look at a simple <a href="http://bea.stollnitz.com/BlogComments/49FilteringHierarchy.zip" rel="nofollow">project</a> that uses a converter for this purpose. The concept is quite simple &#8211; the converter gets added in the ItemsSource Binding, and the filter logic goes in the converter implementation.</p>
<p>&lt;HierarchicalDataTemplate DataType=&#8221;{x:Type local:Lift}&#8221; ItemsSource=&#8221;{Binding Path=Runs, Converter={StaticResource FilterRunsConverter}}&#8221;&gt;<br />
&lt;TextBlock Text=&#8221;{Binding Name}&#8221; /&gt;<br />
&lt;/HierarchicalDataTemplate&gt;</p>
<p>If your data changes, you can write code that ensures that all TreeViewItems are data bound to views that wrap their original collections with the Filter property set. You may also consider adding filtering on the data logic side of the app, instead of using the client-side built-in filtering capabilities of WPF.</p>
<p>In addition, there may be other creative and tricky ways of adding CollectionViewSources with the Filter method directly in XAML, and if you find an elegant way of doing it, please let me know.</p>
<p>Hope this helps.<br />
Bea</p>
]]></content:encoded>
	</item>
</channel>
</rss>
