Как отключить некоторые элементы в XAML для WPF ListView - PullRequest
2 голосов
/ 10 июля 2009

ОК, извините за слишком широкий вопрос, но давайте посмотрим, что вы, ребята, предлагаете ...

У меня есть WPF ListView, загруженный файлом XML с использованием XAML (код ниже)

У меня есть второй файл XML с элементами, которые соответствуют тому, что находится в моем ListView. Однако, если во 2-м файле есть , а не совпадение, то я хочу, чтобы ListItem был отключен.

Простой пример:

В моем ListView есть:

                   Joe
                   Fred
                   Jim  

(потому что он был загружен с первым XML-файлом)

Мой второй XML-файл имеет (по существу):

                  Joe
                  Jim

Я хочу, чтобы 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>

Ответы [ 2 ]

10 голосов
/ 28 июля 2009

Это довольно сложная задача, поэтому вам следует подумать о том, чтобы делать это в основном в коде, а не в XAML. Если бы вы делали это полностью в коде, вы могли бы добавить обработчик для события ListView.Loaded, а затем выполнить всю логику добавления элементов и отключения определенных элементов там. Следует признать, что ListView не будет привязан к данным, но в таком особом случае, как этот, вам может быть лучше без привязки.

Однако, чтобы показать, что это можно сделать в XAML, и используя разметку, подобную вашей, я построил следующий пример. Мой пример использует списки, а не 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 string.

Далее моя разметка 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>

Здесь я связываю свойство IsEnabled каждого ListViewItem со свойством 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();
    }
}

И конечный результат:

alt text

3 голосов
/ 10 июля 2009

Мое решение не так просто, вам нужно создать шаблон данных для элементов в списке. шаблон данных должен иметь источник данных, это означает, что вам нужно иметь какое-то свойство в источнике элементов, которое сообщает вам, существует ли элемент в другом XML-файле.

так что я пытаюсь сказать, что вам нужно прочитать XML-файл из кода и сгенерировать свой собственный класс, который будет содержать имя prop и свойство Exists и связать его с другим файлом,

еще одно решение, о котором я подумал, когда пишу ответ, - связать свойство isenabled элемента с конвертером, который получит имя, проверит другой файл и вернет логическое значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...