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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 05:34:58  来源:igfitidea点击:

WPF - Implement ItemTemplate for an ItemsPresenter?

c#wpfitemtemplateitemspresenter

提问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 ItemTemplateand ItemTemplateSelector(and AlternationCount, okay so 3 properties).

我一直在为 WPF 开发一个 SplitButton 控件,它基本上已经完成,但我正在尝试检查可以在其上设置的所有可能的属性,并确保它们得到实际实现。我主要只剩下两个属性要实现,即ItemTemplateand ItemTemplateSelector(和AlternationCount,好吧,3 个属性)。

I was able to get the HeaderTemplateand HeaderTemplateSelectorworking by binding the ContentTemplateand ContentTemplateSelectorto 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 ItemTemplateand ItemTemplateSelectorproperties for the ItemsPresenter.

我能得到HeaderTemplate并且HeaderTemplateSelector通过绑定工作ContentTemplate,并ContentTemplateSelector给他们上ContentPresenter。这是控件的按钮部分。对于控件的下拉部分,我使用的是 Popup、Border 和ItemsPresenter. 问题是,我想不出如何设置ItemTemplateItemTemplateSelector属性的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 ItemsControlinstead of the ItemsPresenter? This would give you the ItemTemplateand ItemTemplateSelectorproperty as well as the AlternationCountproperty.

您是否考虑过使用ItemsControl代替ItemsPresenter?这会给你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[] ……希望这会有所帮助!