2

I'm trying to display a list of records by unit in separate columns. Everything is working except the binding to filter by unit.

I may be going about this completely the wrong way, but here's what I've got.

public class Record : INotifyPropertyChanged
{
    public string Name { get; set; }
    public string Unit { get; set; }
}
public class UnitList
{
    public ObservableCollection<Record> Items { get; set; }
}

I'm using this markup extension code to do the filtering. In WPF can you filter a CollectionViewSource without code behind?

I can set the PropertyFilter Value statically and it filters fine, but all columns give me the same values. tbUnitName displays the correct value for Unit, but I can't get that same value passed in to the PropertyFilter Value I've tried the ProxyElement/FrameworkElement binding trick and as many different combinations of binding to parent elements as I can think of but I still get 'null' in the filter code.

In the window codebehind I've got:

List<string> names = (from s in this.SelectedSheets.Items
                     where !string.IsNullOrWhiteSpace(s.Unit)
                     select s.Unit).Distinct().ToList();
UnitNames = new ObservableCollection<string>(names);
lbUnits.ItemsSource = UnitNames;

Here's the XAML:

<ListBox Name="lbUnits" >
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Name="spRoster" Orientation="Horizontal" CanHorizontallyScroll="True" CanVerticallyScroll="False" />
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <Grid>
                <TextBox x:Name="tbUnitName" Text="{Binding Path=.}" />
                <ListBox ItemsSource="{Binding }" ItemTemplate="{StaticResource listItemTemplate}" Margin="0,20,0,0" Name="lb1" HorizontalAlignment="Left" VerticalAlignment="Stretch" Width="150" ScrollViewer.CanContentScroll="False" >
                    <ListBox.DataContext>
                        <CollectionViewSource Source="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=Items}" >
                            <!--Filter="FilterOutB"-->
                            <CollectionViewSource.Filter>
                                <local:Filter>
                                    <local:PropertyFilter PropertyName="Unit" Value="{Binding Path=.}" />
                                </local:Filter>
                            </CollectionViewSource.Filter>
                        </CollectionViewSource>
                    </ListBox.DataContext>
                    <ListBox.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel MaxWidth="{Binding ActualWidth, ElementName=lb1}" />
                        </ItemsPanelTemplate>
                    </ListBox.ItemsPanel>
                </ListBox>
            </Grid>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

I think I've solved it. I added

<Grid.Resources>
      <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</Grid.Resources>

and changed the filter to

<local:PropertyFilter PropertyName="Unit" Value="{Binding  Source={StaticResource proxy}}" />
Community
  • 1
  • 1
  • Not sure whether this is your problem. Usually the `CollectionViewSource` is "the man in the middle" between `ItemsSource` and the list property of the view model (and not the `DataContext`). The [MSDN](https://msdn.microsoft.com/en-us/library/system.windows.data.collectionviewsource(v=vs.110).aspx) shows how to do it. – gomi42 Jan 24 '15 at 08:22
  • I maybe missing something but your ListBox ItemsSource is a collection of strings rather than a collection of 'Records' so not sure how it would filter by Unit (of Record) – SWilko Jan 24 '15 at 08:53
  • @gomi42 I'm not sure how or why it works, I'm still trying to figure out all the nuances of bindings and contexts. It's from the sample code and it seems to work. – Mike Cummins Jan 26 '15 at 14:02
  • @dellywheel The outer listbox 'lbUnits' is bound to a collection of unit names. The inner listbox 'lb1' is bound to a collection of records filtered on the value provided in lbUnits. – Mike Cummins Jan 26 '15 at 14:06

0 Answers0