Kev*_*eus 2 c# wpf xaml listview filter
好的,抱歉这个过于宽泛的问题,但让我们看看你们的建议....
我有一个XML文件加载的WPF ListView,使用XAML(下面的代码)
我有第二个XML文件,其中的项目与我的ListView中的项目相匹配.但是,如果第二个文件中没有匹配项,那么我希望禁用ListItem.
一个简单的例子:
我的ListView包含在其中:
Joe
Fred
Jim
Run Code Online (Sandbox Code Playgroud)
(因为它加载了第一个XML文件)
我的第二个XML文件(基本上):
Joe
Jim
Run Code Online (Sandbox Code Playgroud)
我希望ListView以某种方式使用第二个文件,导致"Fred"被禁用.
我假设它将是某种"过滤器"我将在XAML中的某处应用.
<ListView Name="lvwSourceFiles"
Margin="11,93,0,12" VerticalContentAlignment="Center"
HorizontalAlignment="Left" Width="306"
Cursor="Hand" TabIndex="6"
ItemsSource="{Binding}"
SelectionMode="Multiple"
SelectionChanged="lvwSourceFiles_SelectionChanged" >
<ListBox.DataContext>
<XmlDataProvider x:Name="xmlSourceFiles" XPath="AssemblyUpdaterSource/sources/source/File" />
</ListBox.DataContext>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<EventSetter Event="PreviewMouseRightButtonDown"
Handler="OnSourceListViewItemPreviewMouseRightButtonDown" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
Run Code Online (Sandbox Code Playgroud)
Cha*_*lie 10
这是一项相当复杂的任务,因此您应该考虑在代码中而不是在XAML中执行此操作.如果您完全在代码隐藏中执行此操作,则可以为ListView.Loaded事件添加处理程序,然后执行添加项目和禁用某些项目的所有逻辑.不可否认,ListView不会受数据限制,但在这种特殊情况下,如果没有绑定,您可能会更好.
但是,为了表明这可以在XAML中完成,并使用类似于你的标记,我构建了以下示例.我的例子使用Lists而不是XmlDataProvider,但它的要点完全相同; 您只需要使用加载XML的代码替换构建Lists的代码.
这是我的代码隐藏文件:
public partial class Window2 : Window
{
private List<Person> _persons = new List<Person>();
public Window2()
{
InitializeComponent();
_persons.Add(new Person("Joe"));
_persons.Add(new Person("Fred"));
_persons.Add(new Person("Jim"));
}
public List<Person> Persons
{
get { return _persons; }
}
public static List<Person> FilterList
{
get
{
return new List<Person>()
{
new Person("Joe"),
new Person("Jim")
};
}
}
}
public class Person
{
string _name;
public Person(string name)
{
_name = name;
}
public string Name
{
get { return _name; }
set { _name = value; }
}
public override string ToString()
{
return _name;
}
}
Run Code Online (Sandbox Code Playgroud)
这只是定义了几个列表,以及Person类定义,它包含一个Name字符串.
接下来,我的XAML标记:
<Window x:Class="TestWpfApplication.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestWpfApplication"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Window2" Height="300" Width="300"
DataContext="{Binding RelativeSource={RelativeSource Self}}">
<Window.Resources>
<local:PersonInListConverter x:Key="personInListConverter"/>
<ObjectDataProvider x:Key="filterList" ObjectInstance="{x:Static local:Window2.FilterList}"/>
</Window.Resources>
<StackPanel>
<ListView ItemsSource="{Binding Persons}"
SelectionMode="Multiple"
Name="lvwSourceFiles" Cursor="Hand" VerticalContentAlignment="Center">
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsEnabled"
Value="{Binding Name, Converter={StaticResource personInListConverter}, ConverterParameter={StaticResource filterList}}"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
在这里,我将每个ListViewItem的IsEnabled属性绑定到当前Person的Name属性.然后我提供了一个转换器,它将检查该人员名称是否在列表中.ConverterParameter指向FilterList,它等同于您的第二个XML文件.最后,这是转换器:
public class PersonInListConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string name = (string)value;
List<Person> persons = (parameter as ObjectDataProvider).ObjectInstance as List<Person>;
return persons.Exists(person => name.Equals(person.Name));
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Run Code Online (Sandbox Code Playgroud)
最终结果是: