这是一项相当复杂的任务,因此您应该考虑主要在代码中而不是在 XAML 中执行此操作。如果您要完全在代码隐藏中执行此操作,您可以为 ListView.Loaded 事件添加一个处理程序,然后执行添加项目和禁用某些项目的所有逻辑。诚然,ListView 不会是数据绑定的,但在这种特殊情况下,没有绑定可能会更好。
但是,为了表明这可以在 XAML 中完成,并使用与您类似的标记,我构建了以下示例。我的示例使用 Lists 而不是 XmlDataProvider,但其要点完全相同;您只需要用加载 XML 的代码替换我构建列表的代码。
这是我的代码隐藏文件:
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;
}
}
这只是定义了一对列表,以及 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>
这里我将每个 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();
}
}
最终结果: