[英]Custom ItemsControl and selection support
我想创建一个控件:
我已经设法实现了上面列表中的前三点,但是我对第四项有疑问。 我怀疑它可能与项目容器类的错误实现或generic.xaml中的项目模板定义错误有关。
物料容器如下所示:
public class MyEnumSelectorItem : ContentControl
{
public static readonly DependencyProperty IsSelectedProperty;
static MyEnumSelectorItem()
{
IsSelectedProperty = Selector.IsSelectedProperty.AddOwner(typeof(MyEnumSelectorItem));
}
public bool IsSelected
{
get { return (bool)GetValue(IsSelectedProperty); }
set { SetValue(IsSelectedProperty, value); }
}
static readonly DependencyProperty ModeProperty =
DependencyProperty.Register("Mode", typeof(MyEnum), typeof(MyEnumSelector), new PropertyMetadata());
public MyEnum Mode
{
get { return (MyEnum)GetValue(ModeProperty); }
set { SetValue(ModeProperty, value); }
}
}
使用IsItemItsOwnContainerOverride/GetContainerForItemOverride/PrepareContainerForItemOverride
方法重写,将项目容器类型与选择器控件(从System.Windows.Controls.Primitives.Selector
派生)相关联。
generic.xaml的相关片段如下所示:
<Style TargetType="{x:Type controls:MyEnumSelector}">
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<RadioButton Content="{Binding}"
IsChecked="{Binding IsSelected, Mode=TwoWay}"
GroupName="enumSelector" Height="25" FontWeight="Bold" />
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
上面假设IsSelected属性的正确绑定将自动导致设置SelectedItem属性(我希望是正确的,不是吗?)。
在我看来,仅在此处调用Selector.IsSelectedProperty.AddOwner
是不够的。
查看ILSpy中ListBoxItem
的代码,您可以看到可能在完成其他一些事情以在选定项和选择器本身之间进行同步,例如引发Selected / Unselected事件。
static ListBoxItem()
{
ListBoxItem.IsSelectedProperty = Selector.IsSelectedProperty.AddOwner(typeof(ListBoxItem), new FrameworkPropertyMetadata(BooleanBoxes.FalseBox, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault | FrameworkPropertyMetadataOptions.Journal, new PropertyChangedCallback(ListBoxItem.OnIsSelectedChanged)));
ListBoxItem.SelectedEvent = Selector.SelectedEvent.AddOwner(typeof(ListBoxItem));
ListBoxItem.UnselectedEvent = Selector.UnselectedEvent.AddOwner(typeof(ListBoxItem));
...
}
private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ListBoxItem listBoxItem = d as ListBoxItem;
bool flag = (bool)e.NewValue;
Selector parentSelector = listBoxItem.ParentSelector;
if (parentSelector != null)
{
parentSelector.RaiseIsSelectedChangedAutomationEvent(listBoxItem, flag);
}
if (flag)
{
listBoxItem.OnSelected(new RoutedEventArgs(Selector.SelectedEvent, listBoxItem));
}
else
{
listBoxItem.OnUnselected(new RoutedEventArgs(Selector.UnselectedEvent, listBoxItem));
}
listBoxItem.UpdateVisualState();
}
我自己没有尝试过看看是否能真正解决问题,但我认为这是一个不错的起点。 您还应该考虑让项目从ListBoxItem
而不是ContentControl
派生。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.