Setter.TargetName не работает с элементом из настройки BasedOn
У меня есть много экземпляров PathGeometry, которые рисуют различные графики для разных кнопок. Поэтому я создал тип кнопки для отображения Path, который затем обновляет Path. Stroke в зависимости от состояния кнопки. Поэтому покажите его серым, когда мышь отключена, и разными цветами, когда мышь наведена. Стандартные вещи...
<Style x:Key="BasePathButton" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Name="Border"
<Path x:Name="Path" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Path" Property="Stroke" Value="Gray"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Path" Property="Stroke" Value="Green"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Path" Property="Stroke" Value="Red"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Но, очевидно, мне нужны разные Path.Data для каждого экземпляра кнопки. Поэтому я создаю стиль BasedOn для установки Path.Data следующим образом...
<Style x:Key="NLB" TargetType="{x:Type Button}" BasedOn="{StaticResource BasePathButton}">
<Setter TargetName="Path" Property="Data" Value="{StaticResource LeftPathGeometry}"/>
</Style>
... но происходит сбой с ошибкой, что TargetName="Path" не может быть найден. Любые идеи, как это исправить? Или, может быть, лучший способ создать кнопку, которая имеет путь, который параметризован используемой геометрией?
1 ответ
Вы не можете нацеливать элементы в шаблоне через имя, это другая область имен, также я думаю, TargetName
работает только в ControlTemplate.Triggers
, Вы можете ссылаться на данные как DynamicResource
и затем добавьте ресурс к вашим индивидуальным стилям.
например
<Path Data="{DynamicResource PathData}" .../>
<Style x:Key="..." BasedOn="...">
<Style.Resources>
<!-- not sure if this actually works, you could also try DynamicResource here -->
<StaticResource x:Key="PathData" ResourceKey="LeftPathGeometry"/>
</Style.Resources>
</Style>
Вот полный автономный пример, демонстрирующий эту технику (похоже, работает только с динамически скомпилированным XAML!):
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:sys="clr-namespace:System;assembly=mscorlib" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Page.Resources>
<SolidColorBrush x:Key="RedBrush" Color="Red"/>
<SolidColorBrush x:Key="BlueBrush" Color="Blue"/>
<Style x:Key="BaseStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border BorderBrush="{DynamicResource StyleBrush}" BorderThickness="3" Padding="5">
<ContentPresenter TextElement.Foreground="{DynamicResource StyleBrush}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="RedStyle" BasedOn="{StaticResource BaseStyle}" TargetType="Button">
<Style.Resources>
<StaticResource x:Key="StyleBrush" ResourceKey="RedBrush"/>
</Style.Resources>
</Style>
<Style x:Key="BlueStyle" BasedOn="{StaticResource BaseStyle}" TargetType="Button">
<Style.Resources>
<StaticResource x:Key="StyleBrush" ResourceKey="BlueBrush"/>
</Style.Resources>
</Style>
</Page.Resources>
<StackPanel>
<Button Content="Test" Style="{StaticResource RedStyle}"/>
<Button Content="Test" Style="{StaticResource BlueStyle}"/>
</StackPanel>
</Page>