0

我正在尝试根据用户在文本框中键入的内容来过滤列表。但是,当用户在框中输入内容时,什么都没有发生。由于我一直在调试,我已经在设置器上为这个绑定设置了断点,但它们不会触发。

文本框定义:

<TextBox HorizontalAlignment="Center" Text="{Binding TESTSerialNumbSearchTerm, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" ToolTip="Filter Part Number" Width="180"/>

ViewModel 绑定:

public String TESTSerialNumbSearchTerm
{
    get
    {
        return serialNumbSearchTerm;
    }
    set
    {
        if (serialNumbSearchTerm != value)
        {
            serialNumbSearchTerm = value;
            VisibleProfiles = FilterList(VisibleProfiles, Tuple.Create("serialNumber", value));
            OnPropertyChanged(nameof(VisibleProfiles));
            OnPropertyChanged(nameof(TESTSerialNumbSearchTerm));
        }
    }
}

网格定义,带有 ItemSource:

<DataGrid MaxHeight="400" Grid.Row="0" ItemsSource="{Binding VisibleProfiles}" SelectedItem="{Binding SelectedProfile}" SelectionMode="Single" IsReadOnly="True" AutoGenerateColumns="False" VerticalScrollBarVisibility="Visible">

过滤列表方法:

public List<DongleProfile> FilterList(List<DongleProfile> inputList, Tuple<string, string> filter)
{
    List<DongleProfile> newList = new List<DongleProfile>();
    foreach (DongleProfile item in inputList)
    {
        switch (filter.Item1)
        {
            case "serialNumber":
                if (item.SerialNumberPrefix.Contains(filter.Item2))
                {
                    newList.Add(item);
                }
                break;
                // Similar cases
        }
    }
    return newList;
}
4

2 回答 2

1

尝试以下想法:

用于过滤文本框的公共字段

public string md_FilterString
        {
            get { return _FilterString; }
            set
            {
                if (_FilterString != value)
                {
                    _FilterString = value;
                    mf_MakeView();
                    OnPropertyChanged("md_FilterString");
                }
            }
        }

数据网格绑定的公共字段:

public ICollectionView md_LogEntriesStoreView { get; private set; }

XAML:

..
<TextBox Grid.Column="1"
                     Text="{Binding md_FilterString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                     Height="22"
                     HorizontalAlignment="Stretch"
                     Margin="0,0,0,0"
                     Name="textBoxFilter"
                     VerticalAlignment="Center"/>
..
<DataGrid ItemsSource="{Binding md_LogEntriesStoreView, UpdateSourceTrigger=PropertyChanged}"
..
</DataGrid>

mf_MakeView func 配置集合 md_LogEntriesStoreView 的组成:

 private void mf_MakeView()
        {
            if (d_Items== null) return;
            md_LogEntriesStoreView = CollectionViewSource.GetDefaultView(d_Items);
            md_LogEntriesStoreView.Filter = mf_UserFilter;
            OnPropertyChanged("md_LogEntriesStoreView");
        }

其中 d_Items - 直接是您的可观察集合的元素,将显示在控制数据网格中

过滤功能 (mf_UserFilter) 以一般方式呈现给包含文本字段的对象。您可以将其替换为适合您目标的您自己的版本以进行优化:

private bool mf_UserFilter(object item)
        {
            string s = md_FilterString;
            if (String.IsNullOrWhiteSpace(s))
                return true;
            else
            {
                var srcT = item.GetType();
                foreach (var f in srcT.GetFields())
                {
                    string str = f.GetValue(item) as string;
                    if (String.IsNullOrWhiteSpace(str)) continue;
                    bool b = str.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0;
                    if (b) return true;
                }
                foreach (var f in srcT.GetProperties())
                {
                    string str = f.GetValue(item, null) as string;
                    if (String.IsNullOrWhiteSpace(str)) continue;
                    bool b = str.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0;
                    if (b) return true;
                }

                return false;
            }
        }

更新:全文:代码部分:

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.DataContext = new MainWindow_ModelView();
        }
    }

    public class MainWindow_ModelView : NotifyBase
    {
        private string _FilterString = String.Empty;

        public ObservableCollection<ItemClass> d_Items { get; set; }
        public ICollectionView md_LogEntriesStoreView { get; private set; }

        public string md_FilterString
        {
            get { return _FilterString; }
            set
            {
                if (_FilterString != value)
                {
                    _FilterString = value;
                    mf_MakeView();
                    OnPropertyChanged("md_FilterString");
                }
            }
        }

        public MainWindow_ModelView()
        {
            d_Items = new ObservableCollection<ItemClass>() { new ItemClass() { d_Text1 = "Item1Text1", d_Text2 = "Item1Text2" }, 
                new ItemClass() { d_Text1 = "Item2Text1", d_Text2 = "Item2Text2" }, 
                new ItemClass() { d_Text1 = "Item3Text1", d_Text2 = "Item3Text2" } };

            md_LogEntriesStoreView = CollectionViewSource.GetDefaultView(d_Items);
        }

        private void mf_MakeView()
        {
            if (d_Items == null) return;
            md_LogEntriesStoreView = CollectionViewSource.GetDefaultView(d_Items);
            md_LogEntriesStoreView.Filter = mf_UserFilter;
            OnPropertyChanged("md_LogEntriesStoreView");
        }
        private bool mf_UserFilter(object item)
        {
            string s = _FilterString;
            if (String.IsNullOrWhiteSpace(s))
                return true;
            else
            {
                var srcT = item.GetType();
                foreach (var f in srcT.GetFields())
                {
                    string str = f.GetValue(item) as string;
                    if (String.IsNullOrWhiteSpace(str)) continue;
                    bool b = str.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0;
                    if (b) return true;
                }
                foreach (var f in srcT.GetProperties())
                {
                    string str = f.GetValue(item, null) as string;
                    if (String.IsNullOrWhiteSpace(str)) continue;
                    bool b = str.IndexOf(s, StringComparison.OrdinalIgnoreCase) >= 0;
                    if (b) return true;
                }

                return false;
            }
        }
    }

    public class ItemClass : NotifyBase
    {
        public string d_Text1 { get; set; }
        public string d_Text2 { get; set; }
    }

    public class NotifyBase : INotifyPropertyChanged
    {
        Guid id = Guid.NewGuid();

        [Browsable(false)]
        [System.Xml.Serialization.XmlAttribute("ID")]
        public Guid ID
        {
            get { return id; }
            set
            {
                if (id != value)
                {
                    id = value;
                    OnPropertyChanged("ID");
                }
            }
        }

        [field: NonSerialized]
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(String info)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(info));
            }
        }
    }

XAML 部分:

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <TextBox Height="23"
                 Text="{Binding md_FilterString, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                 HorizontalAlignment="Stretch"
                 Name="textBox1"
                 Margin="2"
                 VerticalAlignment="Top"/>
        <DataGrid ItemsSource="{Binding md_LogEntriesStoreView}"
                  AutoGenerateColumns="False"
                  Grid.Row="1"
                  Margin="2"
                  HorizontalAlignment="Stretch"
                  Name="dataGrid1"
                  VerticalAlignment="Stretch">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding Path = d_Text1}"
                                Width="Auto"
                                IsReadOnly="True"/>
                <DataGridTextColumn Binding="{Binding Path = d_Text2}"
                                    Width="*"
                                    IsReadOnly="True" />
             </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

结果:

资源1 资源2

于 2019-10-03T10:17:00.680 回答
1

如果TextBox位于 a 中DataGrid,您可以使用 aRelativeSource绑定到视图模型的属性:

<TextBox HorizontalAlignment="Center" 
         Text="{Binding DataContext.TESTSerialNumbSearchTerm, UpdateSourceTrigger=PropertyChanged, 
            RelativeSource={RelativeSource AncestorType=DataGrid}}" 
         ToolTip="Filter Part Number" Width="180"/>
于 2019-10-03T13:50:08.687 回答