我正在学习如何使用TemplatedControl
创建一个ItemsControl
。我选择ListViewBase
作为满足我要求的基类。 ItemsPresenter
在Popup
中(我在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>
到目前为止,我已经尝试过:
x:Load = true
在弹出窗口中,ItemsPresenter
OnApplyTemplate
谢谢。
请让我知道是否需要更多代码/其他信息。
答案 0 :(得分:0)
使用Microsoft用于默认SplitButton控件(而不是ListViewBase)的方法,您可能会发现更好的成功。
编辑:添加了一个工作示例:
这是扩展SplitButton
的示例,它将为Flyout
设置一个ListView
。 ListView
会自动将选择内容与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=""/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="ChevronUp">
<VisualState.Setters>
<Setter Target="ChevronTextBlock.Text" Value=""/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="ChevronRight">
<VisualState.Setters>
<Setter Target="ChevronTextBlock.Text" Value=""/>
</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="" VerticalAlignment="Center"/>
</Button>
</Grid>
</ControlTemplate>