【发布时间】:2013-04-24 20:44:45
【问题描述】:
我是自定义控件创建的新手。我已经为基于 Selector 类的新自定义控件奠定了一些基础。我的理解是我应该使用这个类,因为我需要控件来拥有一个 Items 集合和处理选择的能力。我相信更改 ItemTemplate 可能会覆盖其中的某些功能,因为我没有在控件级别或应用程序级别收到 SelectionChanged 事件。我想如果我是对的,我可以将 DataTemplate 内部放入某种 SelectionRegion XAML 标记。我没有运气找到这样的东西。在谷歌浏览了一段时间后,我准备问一下。我错过了什么?下面是 ItemTemplate 标记。谢谢你的帮助。如果你能告诉我为什么 TextBlock 中的 Text 被括在括号中,即使数据不是,我也会更加感谢。
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock Text="{Binding}" Foreground="Black" Background="White" MinHeight="12" MinWidth="50"/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
应评论者的要求,这是迄今为止该控件的完整 XAML:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:SourceMedicalWPFCustomControlLibrary">
<Style TargetType="{x:Type local:MultiStateSelectionGrid}">
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<WrapPanel/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1">
<TextBlock Text="{Binding Code}" Foreground="Black" Background="White" MinHeight="12" MinWidth="50" Padding="2" ToolTip="{Binding Description}"/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MultiStateSelectionGrid}">
<StackPanel HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,0" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,0" Content="{TemplateBinding Content}"/>
<ItemsPresenter/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
还有贫血的代码隐藏:
namespace SourceMedicalWPFCustomControlLibrary
{
public class MultiStateSelectionGridState
{
public Brush Background { get; set; }
public Brush Foreground { get; set; }
public Brush Border { get; set; }
public string Text { get; set; }
public MultiStateSelectionGridState()
{
Background = Brushes.White;
Foreground = Brushes.Black;
Border = Brushes.Black;
Text = String.Empty;
}
};
public class MultiStateSelectionGrid : Selector
{
public static readonly DependencyProperty ContentProperty =
DependencyProperty.Register("Content", typeof(object), typeof(MultiStateSelectionGrid),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.AffectsRender |
FrameworkPropertyMetadataOptions.AffectsParentMeasure));
public object Content
{
get { return (object)GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
public static readonly DependencyProperty StatesProperty =
DependencyProperty.Register("States", typeof(List<MultiStateSelectionGridState>), typeof(MultiStateSelectionGrid),
new FrameworkPropertyMetadata(new List<MultiStateSelectionGridState>(),
FrameworkPropertyMetadataOptions.AffectsRender));
public List<MultiStateSelectionGridState> States
{
get { return (List<MultiStateSelectionGridState>)GetValue(StatesProperty); }
set { SetValue(StatesProperty, value); }
}
static MultiStateSelectionGrid()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiStateSelectionGrid), new FrameworkPropertyMetadata(typeof(MultiStateSelectionGrid)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.SelectionChanged += new SelectionChangedEventHandler(MultiStateSelectionGrid_SelectionChanged);
}
void MultiStateSelectionGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
MessageBox.Show("Hi");
}
}
}
【问题讨论】:
-
欢迎堆栈溢出。我们需要更多详细信息,您的控件的完整 xaml 和背后的代码是什么,或者如果使用 mvvm,则查看模型?
-
根据我对选择器类的理解,如果你从它派生,那么选择事件需要自己处理,无论是通过鼠标单击、触摸还是键盘。如果您想要一个已经实现的选择事件,请改用列表视图或列表框。 CMIIW。
-
@dnr3 那么,使用 Selector 类的意义在于它拥有所有支持选择的成员变量?这似乎有点没用。
-
@JKing 在这一点上做得很少,我认为这没有什么坏处。我将添加一个编辑。
-
@BillyD 很抱歉回复晚了,但是这就是我从选择器类中所理解的,我试图创建一个也从它派生的选择器类,但因为我必须控制选择更改事件何时触发(通过单击鼠标或 mouseleftbuttondown 等)并且厌倦了它,我决定使用 listview 作为基本控件。
标签: wpf custom-controls selector itemtemplate selectionchanged