如何过滤ListBox项目?

时间:2011-10-17 13:19:40

标签: wpf silverlight

我定义了这个简单的类

 public class SimpleClass
 {
      public string Val1 {get;set;};
      public string Val2 {get;set;}
      public string Res
      {
            get
            {
                 string.Format("{0}_{1}", Val1, Val2 );
            }
      }

      public SimpleClass(string v1, string v2)
      {
             Val1 = v1;
             Val2 = v2;
      }

      public SimpleClass(string v1, int i)
      {
            if(i == 0)
            {
                 Val1 = v1;
                 val2 = "";
            }

            if(i == 0)
            {
                 Val2 = v1;
                 val1 = "";
            }
      }


 }

现在,我在代码中定义了这个

 List< SimpleClass > myList = new List<SimpleClass>();
 myList.Add(new SimpleClass("a1", "b1");
 myList.Add(new SimpleClass("a2", "b2");
 myList.Add(new SimpleClass("a3", "b3");
 myList.Add(new SimpleClass("a4", "b4");

我在xaml 2 ListBox中定义 -      首先显示所有a1 ... a4项      第二个显示所有b1 ... b4项目

ListBox中的每个项目都是CheckBox - 内容是项目的字符串。

现在我想定义过滤器,它将在其他列表中仅显示在listBox中检查的SimpleClass.Res。

==&GT;这意味着如果在listBox中检查的项目是b1和a3,那么第三个列表框中的唯一文本将包含

       a1_b1
       a3_b3

我该怎么办?

我尝试使用CollectionViewSource,但在这种情况下我无法定义多重过滤器。

3 个答案:

答案 0 :(得分:1)

在SimpleClass中放置一个布尔公共属性并将其绑定到复选框。然后在第二个列表中绑定对属性的可见性。

    <DataTrigger Binding="{Binding Path=DispDetail, Mode=OneWay}" Value="False">
          <Setter Property="Visibility" Value="Collapsed"/>
    </DataTrigger

答案 1 :(得分:1)

如果您的选中项目在ViewModel中,您只需使用委托过滤集合视图来源

ICollectionView view = CollectionViewSource.GetDefaultView(this.myList);
view.Filter = obj =>
{
    var sc = obj as SimpleClass;

    // Do your checks to see if this object is valid, and return a bool
    // For example,
    return SelectedOptions.Contains(sc.Val1) || 
           SelectedOptions.Contains(sc.Val2);
};

return view;

答案 2 :(得分:1)

在用户界面中,您必须将复选框绑定到某个内容,以便您了解两个列表框中已检查项目的状态。

因此我们将它TwoWay绑定到祖先ListBoxItem的{​​{1}}属性。这样,当选中复选框时,它们会自动在IsSelected属性下注册已检查的项目。

基于此,我们执行多重绑定ListBox.SelectedItemsListBox3.ItemsSourceListBox1.SelectedItems。名为ListBox2.SelectedItems的多值转换器只执行两个选定项目列表的并集。

我使用了MergeSelectedItemsHelper Array代替TextBlock List来绑定所有这些ListBox。

<强> XAML:

SimpleClass

代码背后:

现在, <StackPanel Orientation="Vertical"> <StackPanel.Resources> <x:ArrayExtension x:Key="MyArraySource" Type="{x:Type TextBlock}"> <TextBlock Text="A" Tag="A1" DataContext="A_A1"/> <TextBlock Text="B" Tag="B1" DataContext="B_B1"/> <TextBlock Text="C" Tag="C1" DataContext="C_C1"/> <TextBlock Text="D" Tag="D1" DataContext="D_D1"/> </x:ArrayExtension> <local:MergeSelectedItemsHelper x:Key="MergeSelectedItemsHelper"/> <DataTemplate x:Key="ListBox1ItemTemplate"> <CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Mode=TwoWay}" Content="{Binding Text}"/> </DataTemplate> <DataTemplate x:Key="ListBox2ItemTemplate"> <CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Mode=TwoWay}" Content="{Binding Tag}"/> </DataTemplate> </StackPanel.Resources> <ListBox x:Name="ListBox1" SelectionMode="Extended" Margin="10" ItemsSource="{StaticResource MyArraySource}" ItemTemplate="{StaticResource ListBox1ItemTemplate}" SelectionChanged="ListBox1_SelectionChanged"> </ListBox> <ListBox x:Name="ListBox2" SelectionMode="Extended" Margin="10" ItemsSource="{StaticResource MyArraySource}" ItemTemplate="{StaticResource ListBox2ItemTemplate}" SelectionChanged="ListBox1_SelectionChanged"> </ListBox> <ListBox x:Name="ListBox3" Margin="10" DisplayMemberPath="DataContext"> <ListBox.ItemsSource> <MultiBinding Converter="{StaticResource MergeSelectedItemsHelper}"> <Binding Path="SelectedItems" ElementName="ListBox1"/> <Binding Path="SelectedItems" ElementName="ListBox2"/> </MultiBinding> </ListBox.ItemsSource> </ListBox> </StackPanel> </StackPanel> 属性只是一个非依赖属性,也是不可观察的,因此绑定不会自动刷新。在代码背后,当ListBox.SelectedItemsListBox1上的选择发生变化时,我们将很难刷新绑定。

ListBox2

如前所述,多值转换器只是将所选项目连接在一起,并在刷新多重绑定时调用...

    private void ListBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        var bndexp = BindingOperations.GetMultiBindingExpression(
                         ListBox3, ItemsControl.ItemsSourceProperty);
        if (bndexp != null)
        {
            bndexp.UpdateTarget();
        }
    }

希望这有帮助。