代码之家  ›  专栏  ›  技术社区  ›  Muzib hardyVeles

在模板项控件的弹出窗口中,ItemsPresenter在第一次显示时仅显示一个项,在第二次显示时加载所有项

  •  3
  • Muzib hardyVeles  · 技术社区  · 6 年前

    我正在学习如何创建 TemplatedControl 具有 ItemsControl . 我选择了 ListViewBase 因为它符合我的要求。这个 ItemsPresenter Popup (我在 ComboBox ). 我正试图(为了学习的目的)重新创建 ToggleSplitButton 在这里。

    通用.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
            }
        }
    }
    

    主页.xaml 这样地:

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

    大多数事情都很好,除了 弹出式菜单

    enter image description here

    到目前为止我所做的:

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

    提前谢谢。

    如果需要更多代码/附加信息,请告诉我。

    1 回复  |  直到 6 年前
        1
  •  0
  •   Lance McCarthy    6 年前

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

    编辑:添加工作示例:

    Runtime Screenshot

    下面是一个扩展的 SplitButton 这将设置 Flyout ListView . 那个 列表视图 自动将所选内容与 内容:

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