WPF - Расширение ListView с помощью проверяемых и выбираемых ListViewItems - PullRequest
2 голосов
/ 05 мая 2010

Я уже читал много примеров расширения ListViews с помощью флажков, связанных с IsSelected.Но я хочу чего-то большего.

Мне нужно разделение между отмеченным и выбранным состоянием, поэтому я получаю ListBox, который имеет один выбранный элемент, но может иметь несколько отмеченных элементов.К сожалению, ListViewItem не имеет свойства для флажка, и я не вижу возможности заставить ListView работать с пользовательским CheckableListViewItem.

Конечно, я мог бы использовать список объектов с проверенным свойством в качестве ItemSource, но яне думаю, что это хороший способ пойти.Проверено или нет, это вопрос списка или элемента-контейнера, а не объекта, указанного в нем.Кроме того, я не хочу, чтобы все мои классы, такие как пользователь, роль, группа, имели аналоги, такие как checkableUser, checkableRole и checkableGroup.

Требуемое поведение может быть легко реализовано для пользовательского интерфейса с

<DataTemplate x:Key="CheckBoxCell">
   <StackPanel Orientation="Horizontal">
      <CheckBox />
   </StackPanel>
</DataTemplate>

и

<GridViewColumn CellTemplate="{StaticResource CheckBoxCell}" Width="30"/>

Но без привязки к флажку я не могу проверить, отмечен он или нет.

Есть ли способ сделать что-то подобное?Идеальным решением для меня было бы иметь listView1.SelectedItem, listView1.CheckedItems и, возможно, listView1.UncheckedItems и, конечно, listView1.CheckItem и listView1.UncheckItem.

Спасибо за любую помощь.

Ответы [ 2 ]

4 голосов
/ 06 мая 2010

Хорошо, я понял.Делать было не особо много, но, поскольку я новичок во всем, что связано с WPF, нужно было кое-что выяснить.Вот решение:

public class CheckableListViewItem : ListViewItem
{
    [Category("Appearance")]
    [Bindable(true)]
    public bool IsChecked { get; set; }
}

public class CheckableListView : ListView
{
    public IList CheckedItems
    {
        get
        {
            List<object> CheckedItems = new List<object>();
            for (int i=0;i < this.Items.Count; ++i)
            {
                if ((this.ItemContainerGenerator.ContainerFromIndex(i) as CheckableListViewItem).IsChecked)
                    CheckedItems.Add(this.Items[i]);
            }
            return CheckedItems;
        }
    }
    public bool IsChecked(int index)
    {
        if (index < this.Items.Count) return (this.ItemContainerGenerator.ContainerFromIndex(index) as CheckableListViewItem).IsChecked;
        else throw new IndexOutOfRangeException();
    }
    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        if (item is CheckableListViewItem) return true;
        else return false;
    }
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new CheckableListViewItem();
    }
}

Вставьте в свой XAML под Window.Resources (clr = пространство имен моего класса):

<DataTemplate x:Key="CheckBoxCell">
    <StackPanel Orientation="Horizontal">
        <CheckBox IsChecked="{Binding Path=IsChecked, 
            RelativeSource={RelativeSource FindAncestor, 
            AncestorType={x:Type clr:CheckableListViewItem}}}" />
    </StackPanel>
</DataTemplate>

И это как ваш CheckableListView:

<clr:CheckableListView SelectionMode="Single" [...] >
        <ListView.View>
            <GridView>
                <GridViewColumn CellTemplate="{StaticResource CheckBoxCell}" 
                      Width="30"/>
                [...]
            </GridView>
        </ListView.View>
    </clr:CheckableListView>

Может быть, это поможет кому-то с той же проблемой.

1 голос
/ 05 мая 2010

Для этого вам нужно будет создать пользовательские ListBox и пользовательские ListBoxItem элементы управления для использования в вашем приложении. В противном случае вам придется добавить его к элементам в ваших списках в качестве универсального объекта ICheckable<T> (где T - Пользователь или Роль) и иметь ICheckableCollection<ICheckable<T>> для ваших элементов вместо добавления проверяемых объектов вашей модели.

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