C# WPF - 为 ItemsPresenter 实现 ItemTemplate?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1014881/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF - Implement ItemTemplate for an ItemsPresenter?
提问by Thrash505
I've been working on a SplitButton control for WPF and its basically done, but I'm trying to go through all the possible properties that can be set on it and make sure they are actually implemented. I mostly have only two properties left to implement which is the ItemTemplate
and ItemTemplateSelector
(and AlternationCount
, okay so 3 properties).
我一直在为 WPF 开发一个 SplitButton 控件,它基本上已经完成,但我正在尝试检查可以在其上设置的所有可能的属性,并确保它们得到实际实现。我主要只剩下两个属性要实现,即ItemTemplate
and ItemTemplateSelector
(和AlternationCount
,好吧,3 个属性)。
I was able to get the HeaderTemplate
and HeaderTemplateSelector
working by binding the ContentTemplate
and ContentTemplateSelector
to them on a ContentPresenter
. This is for the button part of the control though. For the drop-drop part of the control I'm using a Popup, Border, and ItemsPresenter
. The problem is that I can't figure how to set the ItemTemplate
and ItemTemplateSelector
properties for the ItemsPresenter
.
我能得到HeaderTemplate
并且HeaderTemplateSelector
通过绑定工作ContentTemplate
,并ContentTemplateSelector
给他们上ContentPresenter
。这是控件的按钮部分。对于控件的下拉部分,我使用的是 Popup、Border 和ItemsPresenter
. 问题是,我想不出如何设置ItemTemplate
和ItemTemplateSelector
属性的ItemsPresenter
。
Any ideas?
有任何想法吗?
Update: The full source code for the SplitButton is now available at: http://anothersplitbutton.codeplex.com/
更新:SplitButton 的完整源代码现在可在:http://anothersplitbutton.codeplex.com/
Here's the Luna.NormalColor.xaml file:
这是 Luna.NormalColor.xaml 文件:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:WpfSplitButton="clr-namespace:WpfSplitButton"
xmlns:mwt="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Luna"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- SplitButtonHeader Style -->
<Style x:Key="{x:Type WpfSplitButton:SplitButtonHeader}"
TargetType="{x:Type WpfSplitButton:SplitButtonHeader}">
<Style.Resources>
<Style x:Key="ButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle Margin="2"
StrokeThickness="1"
Stroke="Black"
StrokeDashArray="1 2"
SnapsToDevicePixels="True" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Style.Resources>
<Style.Setters>
<Setter Property="FocusVisualStyle"
Value="{StaticResource ButtonFocusVisual}" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="PastLeftDetection"
Value="True" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<mwt:ButtonChrome x:Name="Chrome"
BorderBrush="{TemplateBinding Border.BorderBrush}"
RenderDefaulted="{TemplateBinding Button.IsDefaulted}"
RenderMouseOver="{TemplateBinding UIElement.IsMouseOver}"
RenderPressed="{TemplateBinding ButtonBase.IsPressed}"
SnapsToDevicePixels="True">
<Grid Background="{TemplateBinding ButtonBase.Background}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"
ContentTemplate="{TemplateBinding ButtonBase.ContentTemplate}"
ContentTemplateSelector="{TemplateBinding ButtonBase.ContentTemplateSelector}"
HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
Margin="{TemplateBinding Control.Padding}"
RecognizesAccessKey="True"
SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" />
<Border x:Name="PART_DropDownInitiator"
Background="Transparent"
BorderBrush="{Binding Path=BorderBrush, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButtonHeader}}}"
BorderThickness="1,0,0,0"
Grid.Column="1"
HorizontalAlignment="Stretch"
Margin="0,0,0,0"
Padding="4,0,4,0"
VerticalAlignment="Stretch">
<Path Fill="{Binding Path=Foreground, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButtonHeader}}}"
VerticalAlignment="Center">
<Path.Style>
<Style>
<Setter Property="Path.Fill"
Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
<Style.Triggers>
<Trigger Property="WpfSplitButton:SplitButton.IsMouseOver"
Value="True">
<Setter Property="Path.Fill"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</Path.Style>
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigureCollection>
<PathFigure IsClosed="True"
StartPoint="0,0">
<PathFigure.Segments>
<PathSegmentCollection>
<LineSegment Point="8,0" />
<LineSegment Point="4,5" />
</PathSegmentCollection>
</PathFigure.Segments>
</PathFigure>
</PathFigureCollection>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>
</Border>
</Grid>
</mwt:ButtonChrome>
<ControlTemplate.Triggers>
<Trigger Property="UIElement.IsKeyboardFocused"
Value="True">
<Setter TargetName="Chrome"
Property="mwt:ButtonChrome.RenderDefaulted"
Value="True" />
</Trigger>
<Trigger Property="ToggleButton.IsChecked"
Value="True">
<Setter TargetName="Chrome"
Property="mwt:ButtonChrome.RenderPressed"
Value="True" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
<!-- SplitButton -->
<Style x:Key="{x:Type WpfSplitButton:SplitButton}"
TargetType="{x:Type WpfSplitButton:SplitButton}">
<Style.Resources>
<LinearGradientBrush x:Key="ButtonNormalBackgroundFill"
EndPoint="0.5,1"
StartPoint="0.5,0">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFFFFFFF"
Offset="0" />
<GradientStop Color="#FFF0F0EA"
Offset="0.9" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush x:Key="ButtonBorder"
Color="#FF003C74" />
</Style.Resources>
<Setter Property="AutoUpdateHeader"
Value="True" />
<Setter Property="Background"
Value="{StaticResource ButtonNormalBackgroundFill}" />
<Setter Property="BorderBrush"
Value="{StaticResource ButtonBorder}" />
<Setter Property="BorderThickness"
Value="1" />
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
<Setter Property="HorizontalContentAlignment"
Value="Center" />
<Setter Property="Padding"
Value="4,4,4,4" />
<Setter Property="VerticalContentAlignment"
Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type WpfSplitButton:SplitButton}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<WpfSplitButton:SplitButtonHeader x:Name="PART_Header"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
ContentTemplateSelector="{TemplateBinding HeaderTemplateSelector}"
Cursor="{TemplateBinding Cursor}"
Foreground="{TemplateBinding Foreground}"
Grid.Row="0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
Padding="{TemplateBinding Padding}"
VerticalAlignment="Stretch"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" />
<Popup x:Name="PART_Popup"
AllowsTransparency="True"
Grid.Row="1"
IsOpen="{Binding Path=IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
MinWidth="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
Placement="Bottom"
PlacementTarget="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}"
StaysOpen="False">
<mwt:SystemDropShadowChrome Color="Transparent">
<Border x:Name="DropDownBorder"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
</mwt:SystemDropShadowChrome>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsEnabled"
Value="False">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
</Trigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
Update 2I tried switching out the ItemsPresenter with a ItemsControl, but I can't seem to get the ItemTemplate property to do anything. Here's the changed section of code:
更新 2我尝试用 ItemsControl 切换 ItemsPresenter,但我似乎无法让 ItemTemplate 属性执行任何操作。这是更改后的代码部分:
<ItemsControl DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
AlternationCount="{TemplateBinding AlternationCount}"
IsTabStop="{TemplateBinding IsTabStop}"
IsTextSearchEnabled="{TemplateBinding IsTextSearchEnabled}"
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
ItemContainerStyleSelector="{TemplateBinding ItemContainerStyleSelector}"
ItemBindingGroup="{TemplateBinding ItemBindingGroup}"
ItemsPanel="{TemplateBinding ItemsPanel}"
ItemsSource="{Binding Path=Items}"
ItemStringFormat="{TemplateBinding ItemStringFormat}"
ItemTemplateSelector="{TemplateBinding ItemTemplateSelector}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="HELLO" />
</DataTemplate>
</ItemsControl.ItemTemplate>
回答by David Rogers
Have you considered using an ItemsControl
instead of the ItemsPresenter
? This would give you the ItemTemplate
and ItemTemplateSelector
property as well as the AlternationCount
property.
您是否考虑过使用ItemsControl
代替ItemsPresenter
?这会给你ItemTemplate
和ItemTemplateSelector
财产以及AlternationCount
财产。
Update:I got it to work just fine using the ItemsControl like you posted above using the following line to bind to the ItemsTemplate Property in your Classic.xaml file:
更新:我使用上面发布的 ItemsControl 让它正常工作,使用以下行绑定到 Classic.xaml 文件中的 ItemsTemplate 属性:
ItemTemplate="{TemplateBinding ItemsTemplate, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"
Then in your MainWindow's Resources i just added the following template:
然后在您的 MainWindow 资源中,我刚刚添加了以下模板:
<DataTemplate x:Key="Test">
<MenuItem Header="{Binding}" />
</DataTemplate>
Then i set the ItemTemplate Property on the SplitButton:
然后我在 SplitButton 上设置 ItemTemplate 属性:
ItemTemplate="{StaticResource Test}"
So just hook up your ItemSource and you are good to go... i just used a simple string[] in the code behind... Hope this helps!
所以只要连接你的 ItemSource 就可以了……我只是在后面的代码中使用了一个简单的 string[] ……希望这会有所帮助!