WPF - 为ItemsPresenter实现ItemTemplate?

时间:2009-06-18 20:02:54

标签: c# wpf itemtemplate itemspresenter

我一直在为WPF开发一个SplitButton控件,它基本完成了,但我正在尝试查看可以在其上设置的所有可能的属性,并确保它们实际实现。我实际上只剩下两个要实现的属性,即ItemTemplateItemTemplateSelector(以及AlternationCount,还有3个属性)。

我能够通过HeaderTemplateHeaderTemplateSelectorContentTemplate绑定到ContentTemplateSelectorContentPresenterItemsPresenter。这是控件的按钮部分。对于控件的drop-drop部分,我使用的是Popup,Border和ItemTemplate。问题是我无法确定如何为ItemTemplateSelector设置ItemsPresenter<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> 属性。

有什么想法吗?


更新: SplitButton的完整源代码现在可在以下位置获得: http://anothersplitbutton.codeplex.com/

这是Luna.NormalColor.xaml文件:

<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>

更新2 我尝试使用ItemsControl切换ItemsPresenter,但我似乎无法获得ItemTemplate属性来执行任何操作。这是改变的代码部分:

{{1}}

1 个答案:

答案 0 :(得分:2)

您是否考虑过使用ItemsControl代替ItemsPresenter?这将为您提供ItemTemplateItemTemplateSelector属性以及AlternationCount属性。

<强>更新 我使用上面发布的ItemsControl,使用以下行绑定到Classic.xaml文件中的ItemsTemplate属性,使其工作正常:

 ItemTemplate="{TemplateBinding ItemsTemplate, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type WpfSplitButton:SplitButton}}}"

然后在您的MainWindow资源中,我添加了以下模板:

<DataTemplate x:Key="Test">
    <MenuItem Header="{Binding}" />
</DataTemplate>

然后我在SplitButton上设置ItemTemplate属性:

ItemTemplate="{StaticResource Test}"

所以只需连接你的ItemSource就可以了...我只是在后面的代码中使用了一个简单的字符串[] ... 希望这有帮助!