C# 过滤器列表视图WPF
我有这个“附加属性”,需要是通用的。在本例中,为了正常工作,我需要强制转换类型为“Employee”的变量。可以创建更通用的东西,总是从“附加属性” 更通用的东西,而不是强制转换为“Employee”,转换为字符串并用于任何listviewC# 过滤器列表视图WPF,c#,wpf,xaml,C#,Wpf,Xaml,我有这个“附加属性”,需要是通用的。在本例中,为了正常工作,我需要强制转换类型为“Employee”的变量。可以创建更通用的东西,总是从“附加属性” 更通用的东西,而不是强制转换为“Employee”,转换为字符串并用于任何listview public static readonly DependencyProperty FilterSourceProperty = DependencyProperty.RegisterAttached("FilterSource", typeof
public static readonly DependencyProperty FilterSourceProperty =
DependencyProperty.RegisterAttached("FilterSource", typeof (TextBox), typeof (ListViewExtension),
new FrameworkPropertyMetadata(null, OnTextBoxSet));
public static TextBox GetFilterSource(DependencyObject dObj)
{
return (TextBox)dObj.GetValue(FilterSourceProperty);
}
public static void SetFilterSource(DependencyObject dObj, TextBox value)
{
dObj.SetValue(FilterSourceProperty, value);
}
private static void OnTextBoxSet(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
{
var listView = dObj as ListView;
var textBox = e.NewValue as TextBox;
if ((listView != null) && (textBox != null))
{
textBox.TextChanged += delegate(object sender, TextChangedEventArgs tcea)
{
var view = CollectionViewSource.GetDefaultView(listView.ItemsSource);
if (view == null) return;
view.Filter += item =>
{
var textFilter = ((TextBox)sender).Text;
var itemPl = (Employee)item;
return itemPl.UserName.Contains(textFilter);
};
};
}
}
In.xaml
<ListView ...>
...
...
tools:ListViewExtension.FilterSource="{Binding ElementName=txtFilter}"
...
...
</ListView
...
...
工具:ListViewExtension.FilterSource=“{Binding ElementName=txtFilter}”
...
...
不需要在OnTextBoxSet
中使用TextBox
试试看:
public static readonly DependencyProperty FilterSourceProperty =
DependencyProperty.RegisterAttached("FilterSource", typeof(string), typeof(Extentions),
new FrameworkPropertyMetadata(null, OnTextBoxSet));
public static string GetFilterSource(DependencyObject dObj)
{
return (string)dObj.GetValue(FilterSourceProperty);
}
public static void SetFilterSource(DependencyObject dObj, string value)
{
dObj.SetValue(FilterSourceProperty, value);
}
private static void OnTextBoxSet(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
{
var listView = dObj as ListView;
var text = e.NewValue as string;
if ((listView == null) || (text == null)) return;
var view = CollectionViewSource.GetDefaultView(listView.ItemsSource);
if (view == null) return;
view.Filter += item =>
{
var itemPl = (Employee) item;
return itemPl.UserName.Contains(text);
};
}
在Xaml中:(设置元素的路径)
谢谢你的帮助,但有两个问题:1)代码不起作用,当我在文本框中键入时没有过滤结果,一定是“textbox.TextChanged”事件的某个地方2)这不是我要求的。我需要避免使用这个“var itemPl=(Employee)项”;我不想隐式转换为“Employee”,我希望是泛型的,并且可以将它用于任何类。@avechuche,现在处于状态,您的问题请等待解决。@avechuche,请测试top的编辑代码,谢谢您的回复。您可以在应用过滤器后选择第一个项目?类似IsSynchronizedWithCurrentItem=“True”的内容。您可以使用以下方法:var item=ListView.Items.GetItemAt(0)代码>测试:>MessageBox.Show((项目为Employee.UserName)代码>在viewmodel中使用MVVM和过滤器
<ListView tools:ListViewExtension.FilterSource="{Binding ElementName=txtFilter,Path=Text,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
private static void OnTextBoxSet(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
{
var listView = dObj as ListView;
var text = e.NewValue as string;
if ((listView == null) || (text == null)) return;
var view = CollectionViewSource.GetDefaultView(listView.ItemsSource);
if (view == null) return;
view.Filter += item =>
{
var type = item.GetType();
if (type == typeof(Employee))
{
var itemPl = (Employee)item;
return itemPl.UserName.Contains(text);
}
if (type == typeof(Person))
{
var itemPl = (Person)item;
return itemPl.Name.Contains(text);
}
//and more types ..............
return false;
};
}