【问题标题】:Filtering under multiple conditions is not working在多个条件下过滤不起作用
【发布时间】:2019-01-03 13:36:55
【问题描述】:

我正在编写一个将虚拟数据加载到数据网格的 WPF 应用程序。数据网格包含以下数据模型:

public class CharacterCollection
  {
    public string Name { get; set; }
    public int Level { get; set; }
    public string Race { get; set; }
    public string Class { get; set; }

    public List<CharacterCollection> GetCharacters()
    {
      List<CharacterCollection> characters = new List<CharacterCollection>();
      characters.Add(new CharacterCollection { Name = "Lothar", Class = "Fighter", Race = "Human", Level = 5 });
      characters.Add(new CharacterCollection { Name = "Turk", Class = "Barbarian", Race = "Half-Orc", Level = 3 });
      characters.Add(new CharacterCollection { Name = "Melian", Class = "Cleric", Race = "Elf", Level = 10 });
      //... there's about 16 more entries, but you get the idea ;)
      return characters;
    }

接下来,我添加了 4 个组合框;每个都填充了 CharacterCollection 中的一个属性

public partial class MainWindow : Window
{
    private CharacterCollection _characters = new CharacterCollection();
    List<CharacterCollection> collection = new List<CharacterCollection>();

    public MainWindow()
    {
      InitializeComponent();

      collection = _characters.GetCharacters();
      dgCharacterChart.ItemsSource = collection;

      var characterNames = collection.Select(c =>c.Name).Distinct().ToList();
      foreach(var item in characterNames)
      {
        CheckBox cb = new CheckBox();
        cb.Content = item.ToString();

        cbName.Items.Add(cb);
      }
      //...the other 3 combo boxes are filled the same way. I know its ugly and I will work on abstracting this a little better :)
   }
}

到目前为止,我得到的是 4 个组合框,其中填充了复选框,用户可以根据需要检查多少。这些将用于过滤。

最后,我有一个过滤按钮...

private void btnFilter_Click(object sender, RoutedEventArgs e)
{
      ICollectionView _characterCollection = CollectionViewSource.GetDefaultView(collection);
      var predicates = new List<Predicate<CharacterCollection>>();

      foreach (CheckBox checkbox in cbName.Items)
      {
        if (checkbox.IsChecked == true)
        {
          predicates.Add(new Predicate<CharacterCollection>(x => x.Name == checkbox.Content.ToString()));
        }
      }

      foreach (CheckBox checkbox in cbClass.Items)
      {
        if (checkbox.IsChecked == true)
        {
          predicates.Add(new Predicate<CharacterCollection>(x => x.Class == checkbox.Content.ToString()));
        }
      }

      foreach (CheckBox checkbox in cbLevel.Items)
      {
        if (checkbox.IsChecked == true)
        {
          predicates.Add(new Predicate<CharacterCollection>(x => x.Level == Convert.ToInt32(checkbox.Content)));
        }
      }

      foreach (CheckBox checkbox in cbRace.Items)
      {
        if (checkbox.IsChecked == true)
        {
          predicates.Add(new Predicate<CharacterCollection>(x => x.Race == checkbox.Content.ToString()));
        }
      }
      _characterCollection.Filter = o =>
      predicates.All(predicate => predicate(o as CharacterCollection));
      dgCharacterChart.ItemsSource = _characterCollection;
 }

当我单击仅选择一个字段的按钮时,例如从 名称 组合框中,它过滤得很好。但是,如果我从 Name 中选择多个条目,或者如果我开始检查其他组合框中的多个条目,那么我的数据网格将显示为空白。当我调试我的代码时,我可以看到我的谓词列表包含我所有标记为已检查的条目,但我的集合计数为 0。有人可以帮我弄清楚为什么我会得到这些结果吗?

提前非常感谢。

【问题讨论】:

  • 过滤后您在哪里为数据网格设置 ItemsSource?
  • @RackM 我更新了我的问题,忘记添加最后一行。当我调试我的代码时,_characterCollection 视图源返回 0,这就是我应用过滤器时数据网格为空的原因
  • 我所做的是 var _itemSourceList = new CollectionViewSource() { Source = ItemGrid }; ICollectionView 项目列表 = _itemSourceList.View; ItemSearchText = textBox.Text; Itemlist.Filter = ItemFilter; ItemsGrid.ItemsSource = 项目列表;其中 ItemGrid 是数据集合
  • @RackM 我想我可以看到您正在通过文本框进行过滤。您能否进一步详细说明,也许以答案的形式提出您的解决方案?
  • 好的,请看一下

标签: c# wpf foreach filtering collectionviewsource


【解决方案1】:

我做了类似的事情,但我确实通过文本框进行过滤。可能会对你有所帮助。

.Xaml如下

 <TextBox FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}"
                                     Background="{x:Null}"
                                     Text="{Binding Item , UpdateSourceTrigger=LostFocus}" Margin="6,0,0,0" BorderThickness="0" PreviewKeyDown="ItemField_PreviewKeyDown" TextChanged="ItemField_TextChanged" IsReadOnly="{Binding IsReadonly}" />

.Xaml.cs如下

private ObservableCollection<ItemGrid> _itemGrid = new ObservableCollection<ItemGrid>();
    public ObservableCollection<ItemGrid> ItemGrid
    {
        get
        {
            return _itemGrid;
        }
        set
        {
            _itemGrid = value;


        }
    }

    private void ItemField_TextChanged(object sender, TextChangedEventArgs e)
    {
        if (isBeginingEdit) return;
        //here we show the item selector and take care of autocomplete
        var textBox = sender as TextBox;
        if (textBox.Text != "")
        {
            var _itemSourceList = new CollectionViewSource() { Source = ItemGrid };
            ICollectionView Itemlist = _itemSourceList.View;
            ItemSearchText = textBox.Text;
            Itemlist.Filter = ItemFilter;
            var count = _itemSourceList.View.Cast<ItemGrid>().Count();
            if (count > 0)
            {
                ItemsGrid.ItemsSource = Itemlist;
            } 
        } 
   }

【讨论】:

  • 感谢您成为唯一的回复者。虽然我确实了解过滤的概念,但我的问题有点复杂。前段时间我做了一个关于使用文本框方法进行过滤的练习。但我的软件会从各种组合框中获取多种条件,以非线性方式过滤我的数据网格。
猜你喜欢
  • 1970-01-01
  • 2020-07-07
  • 2021-04-06
  • 2013-08-11
  • 1970-01-01
  • 2017-08-29
  • 1970-01-01
  • 1970-01-01
  • 2019-06-01
相关资源
最近更新 更多