Я пишу пользовательский элемент управления, который представляет собой ListView, который имеет CheckBox для каждого элемента в ListView, чтобы указать, что элемент выбран. Я смог сделать это с помощью следующего XAML.
<ListView x:Class="CheckedListViewSample.CheckBoxListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<ListView.Style>
<Style TargetType="{x:Type ListView}">
<Setter Property="SelectionMode" Value="Multiple" />
<Style.Resources>
<Style TargetType="ListViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}"
Padding="{TemplateBinding Control.Padding}"
BorderBrush="{TemplateBinding Border.BorderBrush}"
Background="{TemplateBinding Panel.Background}"
SnapsToDevicePixels="True">
<CheckBox IsChecked="{Binding IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}">
<CheckBox.Content>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" />
</CheckBox.Content>
</CheckBox>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
</Style>
</ListView.Style>
</ListView>
Однако я пытаюсь попробовать еще одну функцию. ListView имеет свойство SelectedItems DependencyProperty, которое возвращает коллекцию проверенных элементов. Тем не менее, мне нужно реализовать SelectedValues DependencyProperty. Я также реализую свойство SelectedValuesPath DependencyProperty. Используя SelectedValuesPath, я указываю путь, где находятся значения для каждого выбранного элемента. Поэтому, если мои элементы имеют свойство ID, я могу указать, используя свойство SelectedValuesPath «ID». Свойство SelectedValues затем возвращает коллекцию значений ID. У меня это работает, также используя этот код в коде позади:
using System.Windows;
using System.Windows.Controls;
using System.ComponentModel;
using System.Collections;
using System.Collections.Generic;
namespace CheckedListViewSample
{
/// <summary>
/// Interaction logic for CheckBoxListView.xaml
/// </summary>
public partial class CheckBoxListView : ListView
{
public static DependencyProperty SelectedValuesPathProperty =
DependencyProperty.Register("SelectedValuesPath",
typeof(string),
typeof(CheckBoxListView),
new PropertyMetadata(string.Empty, null));
public static DependencyProperty SelectedValuesProperty =
DependencyProperty.Register("SelectedValues",
typeof(IList),
typeof(CheckBoxListView),
new PropertyMetadata(new List<object>(), null));
[Category("Appearance")]
[Localizability(LocalizationCategory.NeverLocalize)]
[Bindable(true)]
public string SelectedValuesPath
{
get
{
return ((string)(base.GetValue(CheckBoxListView.SelectedValuesPathProperty)));
}
set
{
base.SetValue(CheckBoxListView.SelectedValuesPathProperty, value);
}
}
[Bindable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Category("Appearance")]
public IList SelectedValues
{
get
{
return ((IList)(base.GetValue(CheckBoxListView.SelectedValuesPathProperty)));
}
set
{
base.SetValue(CheckBoxListView.SelectedValuesPathProperty, value);
}
}
public CheckBoxListView()
: base()
{
InitializeComponent();
base.SelectionChanged += new SelectionChangedEventHandler(CheckBoxListView_SelectionChanged);
}
private void CheckBoxListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
List<object> values = new List<object>();
foreach (var item in SelectedItems)
{
if (string.IsNullOrWhiteSpace(SelectedValuesPath))
{
values.Add(item);
}
else
{
try
{
values.Add(item.GetType().GetProperty(SelectedValuesPath).GetValue(item, null));
}
catch { }
}
}
base.SetValue(CheckBoxListView.SelectedValuesProperty, values);
e.Handled = true;
}
}
}
Моя проблема в том, что моя привязка работает только в одну сторону. У меня возникли проблемы при попытке выяснить, как реализовать мой SelectedValues DependencyProperty, чтобы я мог привязать к нему коллекцию значений, и когда элемент управления загружен, CheckBoxes проверяются с элементами, значения которых соответствуют SelectedValues.
Я подумал об использовании события PropertyChangedCallBack, но не могу понять, как мне написать это для достижения своей цели.
Я также не уверен, как найти правильный ListViewItem, чтобы установить его в качестве выбранного.
И, наконец, если я смогу найти ListViewItem и установить для него значение Selected, не будет ли это запускать мое событие SelectionChanged каждый раз, когда я устанавливаю ListViewItem для выбора?