我已经为窗口中的所有按钮构建了一个ControlTemplate
,但是有一个需要额外的触发器,当它被提升时会改变它的内容值。
显然,我不想将此触发器添加到控件模板中,因为它会影响使用此相同控件模板的所有其他按钮。所以我要做的就是将数据触发器添加到按钮特定样式上,然后引用内容名称并直接在我认为很容易的样式中更改它。
这是我到目前为止所得到的:
<Button HorizontalAlignment="Right"
VerticalAlignment="Top"
Width="34"
BorderThickness="0"
Height="30"
Padding="0"
Click="OnMaximiseClick">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource WindowButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=WindowState}" Value="Maximised">
<Setter TargetName="MaxPath"
Property="Data"
Value="F1M0,10L0,3 3,3 3,0 10,0 10,2 4,2 4,3 7,3 7,6 6,6 6,5 1,5 1,10z M1,10L7,10 7,7 10,7 10,2 9,2 9,6 6,6 6,9 1,9z" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
<Path x:Name="MaxPath"
Width="10"
Height="10"
Data="F1M0,0L0,9 9,9 9,0 0,0 0,3 8,3 8,8 1,8 1,3z"
SnapsToDevicePixels="True"
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" />
</Button>
问题在于Setter
无法访问TargetName="MaxPath"
,我也试过{Binding ElementName=MaxPath}
,但我已陷入僵局。我知道我可以在按钮样式中再次构建ControlTemplate
,但它有许多触发器,我不喜欢在两个地方维护,我确信必须有办法做这很快,很容易,但我无法看到它。
是否有引用其Style
内的按钮内容,或者我必须重新构建Path
Buttons
内的ControlTemplate
,然后重新定义所有内容我的Triggers
在这个新的ControlTemplate
?
答案 0 :(得分:1)
从第二个想法开始,你不需要DataTrigger
。只需将2 Path
直接绑定到窗口状态即可。您需要可重复使用的转换器。
下面是一个演示(make按钮可点击并添加到Fill
的绑定):
XAML:
<Button>
<Grid Width="10"
Height="10">
<Path Fill="Black"
Data="F1M0,0L0,9 9,9 9,0 0,0 0,3 8,3 8,8 1,8 1,3z"
Visibility="{Binding WindowState, RelativeSource=RelativeSource FindAncestor, AncestorType=Window}, ConverterParameter=Invert, Converter={local:StateToVisibilityConverter}}" />
<Path Fill="Black"
Data="F1M0,10L0,3 3,3 3,0 10,0 10,2 4,2 4,3 7,3 7,6 6,6 6,5 1,5 1,10z M1,10L7,10 7,7 10,7 10,2 9,2 9,6 6,6 6,9 1,9z"
Visibility="{Binding WindowState, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Converter={local:StateToVisibilityConverter}}" />
</Grid>
</Button>
转换器:
public class StateToVisibilityConverter : MarkupExtension, IValueConverter
{
public StateToVisibilityConverter() { }
public override object ProvideValue(IServiceProvider serviceProvider) => this;
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var result = (WindowState)value == WindowState.Maximized;
if ((string)parameter == "Invert")
result = !result;
return result ? Visibility.Visible : Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); }
}
从第三个想法(仅限xaml):
<Button>
<Path Fill="Black"
Width="10"
Height="10">
<Path.Style>
<Style TargetType="Path">
<Style.Setters>
<Setter Property="Data"
Value="F1M0,10L0,3 3,3 3,0 10,0 10,2 4,2 4,3 7,3 7,6 6,6 6,5 1,5 1,10z M1,10L7,10 7,7 10,7 10,2 9,2 9,6 6,6 6,9 1,9z" />
</Style.Setters>
<Style.Triggers>
<DataTrigger Binding="{Binding WindowState, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}"
Value="Maximized">
<Setter Property="Data"
Value="F1M0,0L0,9 9,9 9,0 0,0 0,3 8,3 8,8 1,1 1,3z" />
</DataTrigger>
</Style.Triggers>
</Style>
</Path.Style>
</Path>
</Button>
答案 1 :(得分:0)
您可能需要一个ControlTemplate:
<Button
... [your other properties here] >
<Button.Template>
<ControlTemplate>
<Path x:Name="MaxPath"
Width="10"
Height="10"
Data="F1M0,0L0,9 9,9 9,0 0,0 0,3 8,3 8,8 1,8 1,3z"
SnapsToDevicePixels="True"
Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}" />
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=WindowState}" Value="Minimised">
<Setter TargetName="MaxPath"
Property="Data"
Value="F1M0,10L0,3 3,3 3,0 10,0 10,2 4,2 4,3 7,3 7,6 6,6 6,5 1,5 1,10z M1,10L7,10 7,7 10,7 10,2 9,2 9,6 6,6 6,9 1,9z" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Button.Template>
</Button>
</Grid>
如果您愿意,可以添加其他触发器。