Как оформить SplitButton
Используя SplitButton из расширенного набора инструментов wpf, я хотел бы использовать стиль, который у меня есть, "blueButtonStyle".
Попытка применить стиль напрямую не работает, так как кнопка действительно не кнопка! Поэтому мне интересно, как подойти к этому.
В идеале на кнопке разделения должно быть свойство кнопки, к которому я мог бы применить blueButtonStyle, но я его не вижу.
Как мне подойти к этому?
Ура,
Berryl
желаемый вид (blueButtonStyle)
внешний вид по умолчанию
текущее определение xaml с ошибкой (неприменимый стиль)
<toolkit:SplitButton DockPanel.Dock="Right" Content="{resx:Resx SplitButton_Add}"
Height="25" Width="80" HorizontalAlignment="Right" Margin="15"
Style="{StaticResource blueButtonStyle}"
>
<toolkit:SplitButton.DropDownContent>
<StackPanel Orientation="Vertical" >
<StackPanel.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource blueButtonStyle}">
</Style>
</StackPanel.Resources>
<Button Content="Person" Command="{Binding AddNewPersonCommand}"/>
<Button Content="Company" Command="{Binding AddNewOrganizationCommand}"/>
</StackPanel>
</toolkit:SplitButton.DropDownContent>
</toolkit:SplitButton>
SplitButton xaml
<!-- =============================================================================== -->
<!-- SplitButton -->
<!-- =============================================================================== -->
<Style TargetType="{x:Type local:SplitButton}">
<Setter Property="BorderThickness" Value="1" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
<Setter Property="Padding" Value="3" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:SplitButton}">
<Grid x:Name="MainGrid" SnapsToDevicePixels="True">
<chrome:ButtonChrome x:Name="ControlChrome" Background="{TemplateBinding Background}" RenderEnabled="{TemplateBinding IsEnabled}" CornerRadius="2.75">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button x:Name="PART_ActionButton" Margin="0"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Padding="{TemplateBinding Padding}" >
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter />
</ControlTemplate>
</Button.Template>
<Grid>
<chrome:ButtonChrome x:Name="ActionButtonChrome"
CornerRadius="2.75, 0, 0, 2.75"
RenderNormal="False"
RenderEnabled="{TemplateBinding IsEnabled}"
RenderMouseOver="{Binding IsMouseOver, ElementName=PART_ActionButton}"
RenderPressed="{Binding IsPressed, ElementName=PART_ActionButton}">
<ContentPresenter Name="ActionButtonContent" Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="true" />
</chrome:ButtonChrome>
</Grid>
</Button>
<ToggleButton x:Name="PART_ToggleButton"
Grid.Column="1"
IsTabStop="False"
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}"
IsHitTestVisible="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}">
<ToggleButton.Template>
<ControlTemplate TargetType="ToggleButton">
<ContentPresenter />
</ControlTemplate>
</ToggleButton.Template>
<Grid>
<chrome:ButtonChrome x:Name="ToggleButtonChrome"
CornerRadius="0, 2.75, 2.75, 0"
RenderNormal="False"
RenderChecked="{TemplateBinding IsOpen}"
RenderEnabled="{TemplateBinding IsEnabled}"
RenderMouseOver="{Binding IsMouseOver, ElementName=PART_ToggleButton}"
RenderPressed="{Binding IsPressed, ElementName=PART_ToggleButton}">
<Grid x:Name="arrowGlyph" IsHitTestVisible="False" Margin="4,3,4,3">
<Path Width="7" Height="4" Data="M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z" Fill="#FF000000" />
</Grid>
</chrome:ButtonChrome>
</Grid>
</ToggleButton>
</Grid>
</chrome:ButtonChrome>
<Popup x:Name="PART_Popup"
HorizontalOffset="1"
VerticalOffset="1"
AllowsTransparency="True"
StaysOpen="False"
Placement="Bottom"
Focusable="False"
IsOpen="{Binding IsChecked, ElementName=PART_ToggleButton}">
<!-- TODO: Create Popup Styles that can be reused on all popups in the toolkit-->
<Border BorderThickness="1" Background="{StaticResource PopupBackgroundBrush}" BorderBrush="{StaticResource ColorPickerDarkBorderBrush}">
<ContentPresenter Content="{TemplateBinding DropDownContent}" />
</Border>
</Popup>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
BlueButtonStyle
<!--BlueButtonStyle-->
<Style x:Key="BlueButtonStyle" TargetType="Button">
<Setter Property="Padding" Value="20,0" />
<Setter Property="Margin" Value="3" />
<Setter Property="Height" Value="23" />
<Setter Property="MinWidth" Value="75" />
<Setter Property="Foreground" Value="White" />
<Setter Property="FocusVisualStyle">
<Setter.Value>
<Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Rectangle RadiusX="5" RadiusY="5" Stroke="Gold" StrokeThickness="1" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid x:Name="rootGrid" RenderTransformOrigin=".5,.5">
<Grid.Resources>
<SolidColorBrush x:Key="borderBrush" Color="Transparent"/>
</Grid.Resources>
<Grid.RenderTransform>
<TranslateTransform X="0" Y="0"/>
</Grid.RenderTransform>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Rectangle Grid.RowSpan="2" x:Name="bottomBorder" RadiusX="5" RadiusY="5"
Stroke="{StaticResource borderBrush}" StrokeThickness="2"
Fill="{StaticResource headerBrush}" />
<Rectangle x:Name="highlight" Margin="2.5" Fill="White" RadiusX="3" RadiusY="3">
<Rectangle.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#D0FFFFFF" Offset="0"/>
<GradientStop Color="#00FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.OpacityMask>
</Rectangle>
<ContentPresenter Grid.RowSpan="2"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
RecognizesAccessKey="True" RenderTransformOrigin="0.5,0.5" x:Name="contentPresenter" />
</Grid>
<ControlTemplate.Resources>
<Storyboard x:Key="buttonDown_Animation">
<DoubleAnimation Storyboard.TargetName="rootGrid"
Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.Y)"
From="0" To="0" Duration="0:0:0"
/>
</Storyboard>
</ControlTemplate.Resources>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="bottomBorder" Property="Stroke" Value="Black" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="bottomBorder" Property="Stroke" Value="Black" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="bottomBorder" Property="Fill" Value="DarkGray" />
<Setter TargetName="bottomBorder" Property="Stroke" Value="Silver" />
<Setter TargetName="bottomBorder" Property="StrokeThickness" Value="4" />
<Setter TargetName="highlight" Property="Fill" Value="#20FFFFFF" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
1 ответ
Первое, что я хотел бы сделать, это убедиться, что BlueButtonStyle действительно применим к этому типу элемента управления.
Стили имеют свойство TargetType, которое необходимо установить, определяющее список свойств, на которые они могут влиять. Ваш стиль должен выглядеть так:
<Style x:Key="blueButtonStyle" TargetType="{x:Type toolkit:SplitButton}">
<!-- edit stuff here -->
</Style>
Теперь, если вы сделали это, но привязка фоновых элементов и прочего в вашем стиле не работает, вам может понадобиться отредактировать ControlTemplate для SplitButton, чтобы учесть этот стиль. ControlTemplate определяет, какие элементы управления составляют данный элемент управления (позвольте мне перефразировать: ControlTemplate для этого SplitButton определяет, какие элементы SubControls вместе взятые составляют этот элемент SplitButton). Если элементы управления в шаблоне ControlTemplate не настроены таким образом, чтобы разрешать привязку таких свойств, как Background и Foreground, тогда стиль не сможет их изменить.
Чтобы получить ControlTemplate, вам понадобится какой-то инструмент декомпиляции. Я использую смесь для этой цели.
Попав в Blend, создайте новый проект и добавьте SplitButton на холст. На панели TreeView внизу слева вы должны увидеть появившуюся кнопку SplitButton. Щелкните правой кнопкой мыши, перейдите к "Редактировать шаблон..." и выберите "Редактировать копию".
Это создаст точную копию ControlTemplate для этого элемента управления, который вы теперь можете использовать, как и любой другой ресурс WPF.
В этом шаблоне вы захотите найти элементы управления, которые составляют SplitButton, который вы хотите стилизовать. На этих элементах управления убедитесь, что свойства, которые вы хотите стилизовать, установлены как TemplateBindings. Они должны выглядеть примерно так:
<ControlTemplate x:Key="splitButtonTemplate" TargetType="{x:Type toolkit:SplitButton}">
<!-- some data here.... -->
<Button Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" />
</ControlTemplate>
Пока свойства, которые вы хотите стилизовать, связаны таким образом, как TemplateBindings, они будут воспринимать изменения, внесенные вашим стилем.