模板化ItemsControl的弹出窗口中的ItemsPresenter在第一个节目中仅显示1个项目,在第二个节目中加载所有内容

时间:2018-12-01 14:25:38

标签: uwp uwp-xaml

我正在学习如何使用TemplatedControl创建一个ItemsControl。我选择ListViewBase作为满足我要求的基类。 ItemsPresenterPopup中(我在ComboBox的模板中找到了它)。我正在尝试在此处重新创建ToggleSplitButton(出于学习目的)。

这是 Generic.xaml 的摘要:

<Style TargetType="local:SplitToggleButton" >

    <!-- other setters.. -->

    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <ItemsStackPanel/>
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>

    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <ListViewItem Content="{Binding}"/>
            </DataTemplate>
        </Setter.Value>
    </Setter>

    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:SplitToggleButton">
                <ContentPresenter x:Name="ContentPresenter" 
                    AutomationProperties.AccessibilityView="Raw" 
                    BackgroundSizing="{TemplateBinding BackgroundSizing}" 
                    Background="{TemplateBinding Background}" 
                    BorderThickness="{TemplateBinding BorderThickness}" 
                    BorderBrush="{TemplateBinding BorderBrush}" 
                    CornerRadius="{TemplateBinding CornerRadius}" 
                    HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" 
                    VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}">

                    <VisualStateManager.VisualStateGroups>
                        <!-- visual state codes -->
                    </VisualStateManager.VisualStateGroups>

                    <Grid x:Name="RootGrid">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition/>
                            <ColumnDefinition Width="auto"/>
                        </Grid.ColumnDefinitions>

                        <ContentPresenter 
                            x:Name="ToggleBtn" 
                            HorizontalAlignment="Stretch"
                            Background="Transparent"
                            Padding="{TemplateBinding Padding}"/>
                        <ContentPresenter 
                            x:Name="OptionBtn" 
                            VerticalAlignment="Stretch"
                            BorderThickness="1 0 0 0"
                            Background="Transparent"
                            BorderBrush="{StaticResource ApplicationForegroundThemeBrush}"
                            Padding="{TemplateBinding SecondaryButtonPadding}"
                            Grid.Column="1">
                            <Grid HorizontalAlignment="Center" VerticalAlignment="Center">
                                <Line X1="0" Y1="0" X2="5" Y2="8" Stroke="{ThemeResource ApplicationForegroundThemeBrush}"/>
                                <Line X1="5" Y1="8" X2="10" Y2="0" Stroke="{ThemeResource ApplicationForegroundThemeBrush}"/>
                            </Grid>
                        </ContentPresenter>
                        <Popup Grid.ColumnSpan="2" x:Name="Popup" IsLightDismissEnabled="True">
                            <Border x:Name="PopupBorder" BackgroundSizing="OuterBorderEdge" Background="{ThemeResource ComboBoxDropDownBackground}" BorderThickness="{ThemeResource ComboBoxDropdownBorderThickness}" BorderBrush="{ThemeResource ComboBoxDropDownBorderBrush}" HorizontalAlignment="Stretch" Padding="{ThemeResource ComboBoxDropdownBorderPadding}">
                                <ScrollViewer x:Name="ScrollViewer" AutomationProperties.AccessibilityView="Raw" Foreground="{ThemeResource ComboBoxDropDownForeground}"  
                                              VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}">
                                    <ItemsPresenter x:Name="Presenter"/>
                                </ScrollViewer>
                            </Border>
                        </Popup>
                    </Grid>
                </ContentPresenter>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

这是UI类的摘要:

using System.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Input;

namespace Test2
{
    public sealed class SplitToggleButton : ListViewBase
    {

        //..dependency properties...

        protected override void OnApplyTemplate()
        {
            base.OnApplyTemplate();


            if(GetTemplateChild("ToggleBtn") is ContentPresenter ToggleBtn)
            {
                ToggleBtn.PointerPressed += SplitToggleButton_PointerPressed;
                ToggleBtn.PointerReleased += SplitToggleButton_PointerExited;

                if (Items.Count > 0)
                {
                    ToggleBtn.Content = Items[0];
                }
                else if(ItemsSource is IList list)
                {
                    ToggleBtn.Content = list[0];
                }
            }


            if (GetTemplateChild("OptionBtn") is ContentPresenter OptionBtn)
            {
                OptionBtn.PointerPressed += OptionBtn_PointerPressed;
            }
        }

        private void OptionBtn_PointerPressed(object sender, PointerRoutedEventArgs e)
        {
            if (GetTemplateChild("Popup") is Popup Popup)
            {
                Popup.IsOpen = true;
            }
        }

        public SplitToggleButton() 
        {
            this.DefaultStyleKey = typeof(SplitToggleButton);

            //.. other codes
        }
    }
}

我在 MainPage.xaml 中使用了它,如下所示:

<local:SplitToggleButton>
    <x:String>something1</x:String>
    <x:String>something2</x:String>
    <x:String>something3</x:String>
</local:SplitToggleButton>

问题:除了Popup在第一个节目中仅显示第一个元素,它就开始显示第二个节目中的所有元素,大多数情况下工作正常,< / p>

enter image description here

到目前为止,我已经尝试过:

  1. x:Load = true在弹出窗口中,ItemsPresenter
  2. FindName(“ Presenter”);在     OnApplyTemplate

谢谢。

请让我知道是否需要更多代码/其他信息。

1 个答案:

答案 0 :(得分:0)

使用Microsoft用于默认SplitButton控件(而不是ListViewBase)的方法,您可能会发现更好的成功。

编辑:添加了一个工作示例:

Runtime Screenshot

这是扩展SplitButton的示例,它将为Flyout设置一个ListViewListView会自动将选择内容与SplitButton同步:

public class CustomSplitButton : SplitButton
{
private readonly ListView _listView;

public CustomSplitButton()
{
    _listView = new ListView();
    _listView.SelectionChanged += ListViewSelectionChanged;

    this.Flyout = new Flyout
    {
        Content = _listView
    };
}

public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register(
    "ItemsSource", typeof(object), typeof(CustomSplitButton), new PropertyMetadata(default(object), ItemsSourceChanged));

private static void ItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is CustomSplitButton self)
    {
        self._listView.ItemsSource = e.NewValue;
    }
}

public object ItemsSource
{
    get => (object)GetValue(ItemsSourceProperty);
    set => SetValue(ItemsSourceProperty, value);
}

private void ListViewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    this.Content = _listView.SelectedItem;
    this.Flyout.Hide();
}
}

可以这样使用:

<local:CustomSplitButton x:Name="MySplitButton" />

并设置自定义ItemsSource属性将自动设置弹出按钮

MySplitButton.ItemsSource = new List<string> {"One", "Two", "Three"};

这不是必需的,但是如果您要编辑SplitButton的ControlTemplate,则为原始文件:

<ControlTemplate x:Key="SplitButtonTemplate1" TargetType="SplitButton">
        <Grid x:Name="RootGrid" Background="{TemplateBinding Background}">
            <Grid.Resources>
                <Style TargetType="Button">
                    <Setter Property="Background" Value="Transparent"/>
                    <Setter Property="Foreground" Value="{ThemeResource SplitButtonForeground}"/>
                    <Setter Property="BorderBrush" Value="Transparent"/>
                    <Setter Property="BorderThickness" Value="{ThemeResource SplitButtonBorderThemeThickness}"/>
                    <Setter Property="HorizontalAlignment" Value="Left"/>
                    <Setter Property="VerticalAlignment" Value="Center"/>
                    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
                    <Setter Property="FontWeight" Value="Normal"/>
                    <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
                    <Setter Property="UseSystemFocusVisuals" Value="{StaticResource UseSystemFocusVisuals}"/>
                    <Setter Property="FocusVisualMargin" Value="-3"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="Button">
                                <Grid x:Name="RootGrid" Background="Transparent">
                                    <VisualStateManager.VisualStateGroups>
                                        <VisualStateGroup x:Name="CommonStates">
                                            <VisualState x:Name="Normal"/>
                                            <VisualState x:Name="Disabled">
                                                <VisualState.Setters>
                                                    <Setter Target="ContentPresenter.Foreground" Value="{ThemeResource SplitButtonForegroundDisabled}"/>
                                                </VisualState.Setters>
                                            </VisualState>
                                        </VisualStateGroup>
                                    </VisualStateManager.VisualStateGroups>
                                    <ContentPresenter x:Name="ContentPresenter" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
                                </Grid>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Grid.Resources>
            <Grid.ColumnDefinitions>
                <ColumnDefinition x:Name="FirstColumn" MinWidth="{ThemeResource SplitButtonPrimaryButtonSize}" Width="*"/>
                <ColumnDefinition x:Name="SecondColumn" Width="{ThemeResource SplitButtonSecondaryButtonSize}"/>
            </Grid.ColumnDefinitions>
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates">
                    <VisualState x:Name="Normal"/>
                    <VisualState x:Name="FlyoutOpen">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="{ThemeResource SplitButtonBackgroundPressed}"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushPressed}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundPressed}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundPressed}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="TouchPressed">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="{ThemeResource SplitButtonBackgroundPressed}"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushPressed}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundPressed}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundPressed}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="PrimaryPointerOver">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="Transparent"/>
                            <Setter Target="PrimaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundPointerOver}"/>
                            <Setter Target="PrimaryButton.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushPointerOver}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundPointerOver}"/>
                            <Setter Target="SecondaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackground}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="PrimaryPressed">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="Transparent"/>
                            <Setter Target="PrimaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundPressed}"/>
                            <Setter Target="PrimaryButton.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushPressed}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundPressed}"/>
                            <Setter Target="SecondaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackground}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="SecondaryPointerOver">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="Transparent"/>
                            <Setter Target="PrimaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackground}"/>
                            <Setter Target="SecondaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundPointerOver}"/>
                            <Setter Target="SecondaryButton.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushPointerOver}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundPointerOver}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="SecondaryPressed">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="Transparent"/>
                            <Setter Target="PrimaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackground}"/>
                            <Setter Target="SecondaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundPressed}"/>
                            <Setter Target="SecondaryButton.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushPressed}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundPressed}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="Checked">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="{ThemeResource SplitButtonBackgroundChecked}"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushChecked}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundChecked}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundChecked}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="CheckedFlyoutOpen">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="{ThemeResource SplitButtonBackgroundCheckedPressed}"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushCheckedPressed}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundCheckedPressed}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundCheckedPressed}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="CheckedTouchPressed">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="{ThemeResource SplitButtonBackgroundCheckedPressed}"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushCheckedPressed}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundCheckedPressed}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundCheckedPressed}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="CheckedPrimaryPointerOver">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="Transparent"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushChecked}"/>
                            <Setter Target="PrimaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundCheckedPointerOver}"/>
                            <Setter Target="PrimaryButton.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushCheckedPointerOver}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundCheckedPointerOver}"/>
                            <Setter Target="SecondaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundChecked}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundChecked}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="CheckedPrimaryPressed">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="Transparent"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushChecked}"/>
                            <Setter Target="PrimaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundCheckedPressed}"/>
                            <Setter Target="PrimaryButton.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushCheckedPressed}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundCheckedPressed}"/>
                            <Setter Target="SecondaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundChecked}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundChecked}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="CheckedSecondaryPointerOver">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="Transparent"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushChecked}"/>
                            <Setter Target="PrimaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundChecked}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundChecked}"/>
                            <Setter Target="SecondaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundCheckedPointerOver}"/>
                            <Setter Target="SecondaryButton.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushCheckedPointerOver}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundCheckedPointerOver}"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="CheckedSecondaryPressed">
                        <VisualState.Setters>
                            <Setter Target="RootGrid.Background" Value="Transparent"/>
                            <Setter Target="Border.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushChecked}"/>
                            <Setter Target="PrimaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundChecked}"/>
                            <Setter Target="PrimaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundChecked}"/>
                            <Setter Target="SecondaryBackgroundGrid.Background" Value="{ThemeResource SplitButtonBackgroundCheckedPressed}"/>
                            <Setter Target="SecondaryButton.BorderBrush" Value="{ThemeResource SplitButtonBorderBrushCheckedPressed}"/>
                            <Setter Target="SecondaryButton.Foreground" Value="{ThemeResource SplitButtonForegroundCheckedPressed}"/>
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="SecondaryButtonPlacementStates">
                    <VisualState x:Name="SecondaryButtonRight"/>
                    <VisualState x:Name="SecondaryButtonSpan">
                        <VisualState.Setters>
                            <Setter Target="SecondaryButton.(Grid.Column)" Value="0"/>
                            <Setter Target="SecondaryButton.(Grid.ColumnSpan)" Value="2"/>
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
                <VisualStateGroup x:Name="ChevronDirectionStates">
                    <VisualState x:Name="ChevronDown"/>
                    <VisualState x:Name="ChevronLeft">
                        <VisualState.Setters>
                            <Setter Target="ChevronTextBlock.Text" Value="&#xE76B;"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="ChevronUp">
                        <VisualState.Setters>
                            <Setter Target="ChevronTextBlock.Text" Value="&#xE70E;"/>
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="ChevronRight">
                        <VisualState.Setters>
                            <Setter Target="ChevronTextBlock.Text" Value="&#xE76C;"/>
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Grid x:Name="PrimaryBackgroundGrid"/>
            <Grid x:Name="SecondaryBackgroundGrid" Grid.Column="1"/>
            <Grid x:Name="Border" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Grid.ColumnSpan="2"/>
            <Button x:Name="PrimaryButton" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Transparent" Command="{TemplateBinding Command}" CommandParameter="{TemplateBinding CommandParameter}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentTransitions="{TemplateBinding ContentTransitions}" Grid.Column="0" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Stretch" Padding="{TemplateBinding Padding}" VerticalAlignment="Stretch"/>
            <Button x:Name="SecondaryButton" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Transparent" Grid.Column="1" Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Padding="0,0,8,0" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch">
                <TextBlock x:Name="ChevronTextBlock" FontFamily="Segoe MDL2 Assets" FontSize="12" HorizontalAlignment="Right" Text="&#xE70D;" VerticalAlignment="Center"/>
            </Button>
        </Grid>
    </ControlTemplate>