简体   繁体   English

WPF-为ItemsPresenter实现ItemTemplate?

[英]WPF - Implement ItemTemplate for an ItemsPresenter?

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. 我一直在为WPF开发一个SplitButton控件,并且基本上已经完成了,但是我正在尝试遍历可以在其上设置的所有可能的属性,并确保它们实际上已实现。 I mostly have only two properties left to implement which is the ItemTemplate and ItemTemplateSelector (and AlternationCount , okay so 3 properties). 我几乎只剩下两个要实现的属性,即ItemTemplateItemTemplateSelector (和AlternationCount ,好的3个属性)。

I was able to get the HeaderTemplate and HeaderTemplateSelector working by binding the ContentTemplate and ContentTemplateSelector to them on a ContentPresenter . 通过将ContentTemplateContentTemplateSelector绑定到ContentPresenter上,我能够使HeaderTemplateHeaderTemplateSelector正常工作。 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 . 对于控件的下拉部分,我使用Popup,Border和ItemsPresenter The problem is that I can't figure how to set the ItemTemplate and ItemTemplateSelector properties for the ItemsPresenter . 问题是我不知道如何为ItemsPresenter设置ItemTemplateItemTemplateSelector属性。

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 2 I tried switching out the ItemsPresenter with a ItemsControl, but I can't seem to get the ItemTemplate property to do anything. 更新2我尝试使用ItemsControl切换ItemsPresenter,但似乎无法让ItemTemplate属性执行任何操作。 Here's the changed section of code: 这是代码的更改部分:

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

Have you considered using an ItemsControl instead of the ItemsPresenter ? 您是否考虑过使用ItemsControl代替ItemsPresenter This would give you the ItemTemplate and ItemTemplateSelector property as well as the AlternationCount property. 这将为您提供ItemTemplateItemTemplateSelector属性以及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 [],希望这会有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM