WPF组合框文本搜索,包含
如何使用WPF组合框文本搜索,包含,wpf,search,combobox,Wpf,Search,Combobox,如何使用contains而不是StartsWith实现组合框文本搜索 <rf:ComboBox Grid.Row="1" Grid.Column="5" Width="200" ItemsSource="{Binding Source={StaticResource AccountProvider}}"
contains
而不是StartsWith
实现组合框文本搜索
<rf:ComboBox Grid.Row="1"
Grid.Column="5"
Width="200"
ItemsSource="{Binding Source={StaticResource AccountProvider}}"
DisplayMemberPath="Description"
SelectedValuePath="IndRekId"
IsEmptyItemVisible="True"
SelectedValue="{Binding Id, UpdateSourceTrigger=PropertyChanged}"
IsTextSearchEnabled="True"
TextSearch.TextPath="Description"
IsEditable="True"/>
搜索函数可以工作,但我需要匹配子字符串,无法用string.Contains()替换string.StartsWith()。您必须编写自定义组合框 本文可能会帮助您:
这里我有一个MVVM框架的例子 我的xaml文件:
<ComboBox Name="cmbContains" IsEditable="True" IsTextSearchEnabled="false" ItemsSource="{Binding pData}" DisplayMemberPath="wTitle" Text="{Binding SearchText ,Mode=TwoWay}" >
<ComboBox.Triggers>
<EventTrigger RoutedEvent="TextBoxBase.TextChanged">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsDropDownOpen">
<DiscreteBooleanKeyFrame Value="True" KeyTime="0:0:0"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ComboBox.Triggers>
</ComboBox>
我的cs文件:
//ItemsSource - pData
//There is a string attribute - wTitle included in the fooClass (DisplayMemberPath)
private ObservableCollection<fooClass> __pData;
public ObservableCollection<fooClass> pData {
get { return __pData; }
set { Set(() => pData, ref __pData, value);
RaisePropertyChanged("pData");
}
}
private string _SearchText;
public string SearchText {
get { return this._SearchText; }
set {
this._SearchText = value;
RaisePropertyChanged("SearchText");
//Update your ItemsSource here with Linq
pData = new ObservableCollection<fooClass>{pData.ToList().Where(.....)};
}
}
//ItemsSource-pData
//fooClass(DisplayMemberPath)中包含一个字符串属性-wTitle
私有可观测收集数据;
公共可观测收集pData{
获取{return\uu pData;}
set{set(()=>pData,ref u pData,value);
RaisePropertyChanged(“pData”);
}
}
私有字符串_SearchText;
公共字符串搜索文本{
获取{返回此。\u SearchText;}
设置{
这是。_SearchText=value;
RaisePropertyChanged(“搜索文本”);
//使用Linq在此处更新您的ItemsSource
pData=新的ObservableCollection{pData.ToList()。其中(…)};
}
}
您可以看到可编辑组合框绑定到字符串(SearchText)
一旦出现TextChanged事件,将显示下拉列表,双向绑定将更新该值。
cs文件中的ItemsSource在进入集合{}时发生了更改;语法
此示例看起来像“文本搜索”
在XAML文件中,您应该只向组合框“TextContainSearch.Text”添加一个属性:
和*.cs文件中的C#代码:
using System;
using System.Windows;
using System.Windows.Controls;
namespace Adaptive.Controls.Extension
{
public sealed class TextContainSearch : DependencyObject {
public static void SetText(DependencyObject element, string text) {
var controlSearch = element as Control;
if (controlSearch != null)
controlSearch.KeyUp += (sender, e) =>
{
if (sender is ComboBox){
var control = sender as ComboBox;
control.IsDropDownOpen = true;
var oldText = control.Text;
foreach(var itemFromSource in control.ItemsSource){
if (itemFromSource != null)
{
Object simpleType = itemFromSource.GetType().GetProperty(text).GetValue(itemFromSource, null);
String propertOfList = simpleType as string;
if (!string.IsNullOrEmpty(propertOfList) && propertOfList.Contains(control.Text))
{
control.SelectedItem = itemFromSource;
control.Items.MoveCurrentTo(itemFromSource);
break;
}
}
}
control.Text = oldText;
TextBox txt = control.Template.FindName("PART_EditableTextBox", control) as TextBox;
if (txt != null)
{
txt.Select(txt.Text.Length, 0);
}
}
};
}
}
}
试试这个:
<ComboBox Padding="3,5" MinWidth="150" SelectedItem="{Binding NewBoxRequest}"
ItemsSource="{Binding Requests}" DisplayMemberPath="SN" IsEditable="True"
StaysOpenOnEdit="True"
Text="{Binding SnFilter,UpdateSourceTrigger=PropertyChanged}">
</ComboBox>
视图模型:
private string snFilter;
public string SnFilter
{
get { return snFilter; }
set
{
snFilter = value;
RaisePropertyChanged();
RaisePropertyChanged(nameof(Requests));
}
}
private List<Request> requests;
public List<Request> Requests
{
get => string.IsNullOrEmpty(SnFilter) || requests.Any(r => r.SN == SnFilter)
? requests
: requests.Where(r => r.SN.Contains(SnFilter)).ToList();
set
{
requests = value;
RaisePropertyChanged();
}
}
私有字符串snFilter;
公共字符串SnFilter
{
获取{return snFilter;}
设置
{
snFilter=值;
RaisePropertyChanged();
RaisePropertyChanged(请求名称));
}
}
私人名单请求;
公开列表请求
{
get=>string.IsNullOrEmpty(SnFilter)| | requests.Any(r=>r.SN==SnFilter)
?请求
:requests.Where(r=>r.SN.Contains(SnFilter)).ToList();
设置
{
请求=价值;
RaisePropertyChanged();
}
}
我无法让“Set”语法在我的C#系统中工作,因此这里是对上面Wu的答案的一个小小的补充(这是在一个自定义控件中):
在自定义控件中:
<ComboBox IsEditable="True"
IsTextSearchEnabled="false"
ItemsSource="{Binding pData, RelativeSource = {RelativeSource TemplatedParent}}"
DisplayMemberPath="description"
Text="{Binding SearchText , RelativeSource = {RelativeSource TemplatedParent}, Mode=TwoWay}" >
<ComboBox.Triggers>
<EventTrigger RoutedEvent="TextBoxBase.TextChanged">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsDropDownOpen">
<DiscreteBooleanKeyFrame Value="True" KeyTime="0:0:0"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ComboBox.Triggers>
</ComboBox>
private async void _Loaded(object sender, RoutedEventArgs e)
{
var n = await InitializeLabTests;
allTests = new ObservableCollection<CommonProcedure>(n);
pData = new ObservableCollection<CommonProcedure>(n);
}
//ItemsSource - pData
//There is a string attribute - wTitle included in the fooClass (DisplayMemberPath)
private ObservableCollection<CommonProcedure> __pData;
public ObservableCollection<CommonProcedure> pData
{
get { return __pData; }
set { __pData = value; RaisePropertyChanged(); }
}
private string _SearchText;
public string SearchText
{
get { return _SearchText; }
set
{
_SearchText = value; RaisePropertyChanged();
//Update your ItemsSource here with Linq
pData = new ObservableCollection<CommonProcedure>
(
allTests.Where(q => q.description.Contains(SearchText))
);
}
}
private async void\u已加载(对象发送方,RoutedEventArgs e)
{
var n=等待初始化测试;
所有测试=新的可观察收集(n);
pData=新的可观测集合(n);
}
//ItemsSource-pData
//fooClass(DisplayMemberPath)中包含一个字符串属性-wTitle
私有可观测收集数据;
公共可观测收集pData
{
获取{return\uu pData;}
设置{uuu pData=value;RaisePropertyChanged();}
}
私有字符串_SearchText;
公共字符串搜索文本
{
获取{return\u SearchText;}
设置
{
_SearchText=value;RaisePropertyChanged();
//使用Linq在此处更新您的ItemsSource
pData=新的可观测采集
(
其中(q=>q.description.Contains(SearchText))
);
}
}
唯一显著的区别在于SearchText setter。据我所知,实现这一点的唯一方法是创建一个扩展ComboBox的控件,并添加所需的功能。此代码段中的模式是什么?我知道附加的属性,并且大部分时间都使用它们来完成这个代码段所做的事情——注册到控件的事件。虽然我从未见过这种情况,并且对您的方法的工作方式非常感兴趣。Hi@Evgenii,但是inSetText(DependencyObject元素,string text),“text”参数的值始终是“DeviceNumber”字符串。所以我输入的文本没有反映在那里。有什么原因吗?
<ComboBox IsEditable="True"
IsTextSearchEnabled="false"
ItemsSource="{Binding pData, RelativeSource = {RelativeSource TemplatedParent}}"
DisplayMemberPath="description"
Text="{Binding SearchText , RelativeSource = {RelativeSource TemplatedParent}, Mode=TwoWay}" >
<ComboBox.Triggers>
<EventTrigger RoutedEvent="TextBoxBase.TextChanged">
<BeginStoryboard>
<Storyboard>
<BooleanAnimationUsingKeyFrames Storyboard.TargetProperty="IsDropDownOpen">
<DiscreteBooleanKeyFrame Value="True" KeyTime="0:0:0"/>
</BooleanAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ComboBox.Triggers>
</ComboBox>
private async void _Loaded(object sender, RoutedEventArgs e)
{
var n = await InitializeLabTests;
allTests = new ObservableCollection<CommonProcedure>(n);
pData = new ObservableCollection<CommonProcedure>(n);
}
//ItemsSource - pData
//There is a string attribute - wTitle included in the fooClass (DisplayMemberPath)
private ObservableCollection<CommonProcedure> __pData;
public ObservableCollection<CommonProcedure> pData
{
get { return __pData; }
set { __pData = value; RaisePropertyChanged(); }
}
private string _SearchText;
public string SearchText
{
get { return _SearchText; }
set
{
_SearchText = value; RaisePropertyChanged();
//Update your ItemsSource here with Linq
pData = new ObservableCollection<CommonProcedure>
(
allTests.Where(q => q.description.Contains(SearchText))
);
}
}