2011-10-17 95 views
1

我定義這個簡單的類如何過濾ListBox項目?

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列表框定義 - 首先,顯示所有的A1 ... A4項目 其次顯示所有b1 ... b4項目

ListBox中的每個項目都是複選框 - 並且內容是項目的字符串。

現在我想定義過濾器,它將顯示在其他列表中只顯示列表框中選中的SimpleClass.Res。

==>這意味着,如果在這是檢查的項目是B1和A3列表框,在列表框中第三隻文本將包含

 a1_b1 
     a3_b3 

我該怎麼辦呢?

我想使用CollectionViewSource,但我不能在這種情況下定義多個過濾器。

+0

什麼是單獨的CheckBox綁定? – 2011-10-17 13:38:25

+0

什麼都沒有。只是從出現在複選框上的文本中過濾 – Yanshof 2011-10-17 13:45:02

+0

您是否在嘗試實現多選?如果是這樣,那麼複選框必須綁定到某個不是它? – 2011-10-17 13:45:32

回答

1

在UI過濾收集查看源代碼,你必須有必然的東西,這樣你的複選框知道兩個列表框中選中項目的狀態。

因此我們將它綁定到TwoWay到祖先ListBoxItemIsSelected屬性。通過這種方式,當複選框被選中時,他們自動將檢查項目註冊到ListBox.SelectedItems屬性下。

基於此,我們執行多重綁定ListBox3.ItemsSourceListBox1.SelectedItemsListBox2.SelectedItems。稱爲MergeSelectedItemsHelper的多值轉換器僅執行兩個選定項目列表的聯合。

我用的TextBlock代替的SimpleClassListArray綁定到所有這些列表框。

XAML:

<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.SelectedItems財產僅僅是一種非依賴項屬性,也不可觀察這樣的綁定不會自動刷新。在後面的代碼中,當ListBox1ListBox2上的選擇更改時,我們需要刷新綁定。

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

正如前面所說的,多值轉換器只需加入選定的項目一起,多結合被刷新時被調用......

public class MergeSelectedItemsHelper : IMultiValueConverter 
{ 

    #region IMultiValueConverter Members 

    public object Convert(
      object[] values, 
      Type targetType, 
      object parameter, 
      System.Globalization.CultureInfo culture) 
    { 

     var list1 = values[0] as IList; 
     var list2 = values[1] as IList; 

     var validList2 = list2 ?? new List<object>(); 

     return list1 != null 
       ? list1.Cast<object>().Union(validList2.Cast<object>()) 
        : validList2.Cast<object>(); 
    } 

    public object[] ConvertBack(
      object value, 
      Type[] targetTypes, 
      object parameter, 
      System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

希望這有助於。

0

在SimpleClass中放置一個布爾公共屬性並將其綁定到複選框。然後在第二個列表中綁定對該屬性的可見性。

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

如果你檢查的項目是在你的視圖模型,你可以簡單地使用委託

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;