У меня есть 3 TextBlocks, свойство видимости которых зависит от правила проверки 3 различных элементов (TextBoxes). Как я могу реорганизовать этот код так, чтобы ElementName абстрагировался, и у меня был только один определенный стиль вместо 3? Можно ли передать ElementName в качестве параметра в TextBlocks, к которым применяется этот стиль?
<Style x:Key="textBlock_stockPriceWarning" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), ElementName=stockPriceTextBox}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=(Validation.HasError), ElementName=stockPriceTextBox}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="textBlock_taxRateWarning" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), ElementName=ordinaryTaxRateBox}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=(Validation.HasError), ElementName=ordinaryTaxRateBox}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="textBlock_capGainsTaxRateWarning" TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError), ElementName=capitalGainsTaxRateBox}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=(Validation.HasError), ElementName=capitalGainsTaxRateBox}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
** Обновление: следуя совету Марка ниже, я попытался использовать следующий ControlTemplate и определение присоединенного свойства:
<ControlTemplate x:Key="LabelWarning" TargetType="Label">
<Border BorderBrush="AliceBlue"/>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=(Validation.HasError),
ElementName={Binding Path=(views:ElementNameHelper.ElementAlias), RelativeSource={RelativeSource Mode=TemplatedParent}}}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=(Validation.HasError),
ElementName={Binding Path=(views:ElementNameHelper.ElementAlias), RelativeSource={RelativeSource Mode=TemplatedParent}}}" Value="False">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
public static class ElementNameHelper
{
public static readonly DependencyProperty ElementAliasProperty =
DependencyProperty.RegisterAttached("ElementAlias",
typeof(string), typeof(ElementNameHelper));
public static string GetElementAlias(DependencyObject obj)
{
return obj.GetValue(ElementAliasProperty).ToString();
}
public static void SetElementAlias(DependencyObject target, string value)
{
target.SetValue(ElementAliasProperty, value);
}
}
И вызывая его так:
<Label Content="Stock price should be a positive number."
FontSize="12" HorizontalAlignment="Center"
VerticalAlignment="Center" Foreground="Red"
Margin="1"
views:ElementNameHelper.ElementAlias="stockPriceTextBox"
Template="{StaticResource LabelWarning}"/>
Но тогда компилятор XAML говорит мне, что: «Binding» не может быть установлен в свойстве «ElementName» типа «Binding» , «Связывание» может быть установлено только для свойства DependencyObject объекта DependencyObject. Правильно ли я настроил эту настройку, и вы просто не можете использовать этот подход в ElementName? Или я что-то упустил с определением прикрепленного свойства?