我有几个按钮,它们将共享一个共同的样式,它们都将具有基于绑定属性的DataTriggers。我试图避免为每个按钮写出每个数据触发器,所以我想知道是否有办法动态指定DataTrigger.Binding的路径?
例如:
<DataTrigger
Binding="{Binding Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}},
Path={Binding RelativeSource={RelativeSource Self}, Path=Tag}}" Value="True">
<!--Do Something-->
</DataTrigger>
我知道这可能不可能,但我想我会试一试。我将属性名称存储为每个按钮上的Tag,并且该属性应该在单击时更改。所以我想使用存储在Tag名称中的值作为默认样式的数据触发器上的Path。这是一个示例按钮,用于加粗一些文字:
<Button Content="B" Tag="IsBold" Click="Button_Click" Style="{StaticResource DefaultButton}"/>
以下是使用的风格:
<Style TargetType="{x:Type Button}" x:Key="DefaultButton">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Width" Value="20"/>
<Setter Property="Height" Value="20"/>
<Setter Property="Margin" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" Padding="2" Width="{TemplateBinding Width}" Height="{TemplateBinding Height}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="LightBlue"/>
<Setter Property="BorderBrush" Value="Blue"/>
</Trigger>
<DataTrigger Binding="{Binding Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path={Binding RelativeSource={RelativeSource Self}, Path=Tag}}" Value="True">
</DataTrigger>
</Style.Triggers>
</Style>
显然,由于DataTrigger,此时样式无效。有没有办法让这类东西完全动态,还是我必须绑定每一个按钮?
我已经尝试过使用ValueConverters,并且根据我的需要,我不相信它们会起作用,因为它们只会在初始化时触发一次。
使用更多信息进行更新:
我有一个数据对象作为一种视图。对于所有意图和目的,让我们说它就是它的全部内容:
using System;
using mshtml;
using System.Windows.Controls;
using System.Windows.Media;
using System.Reflection;
using System.ComponentModel;
namespace Aspen.Visuals
{
public class HtmlFormattingExecutor : INotifyPropertyChanged
{
public HtmlFormattingExecutor(HTMLDocument doc)
{
this.doc = doc;
this.isBold = false;
}
private HTMLDocument doc;
private Boolean isBold;
public Boolean IsBold {
get {return this.isBold;}
set
{
if(this.isBold != value)
{
this.isBold = value;
this.Bold();
this.NotifyPropertyChanged("IsBold");
}
}
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
if (this.PropertyChanged != null)
this.PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
private void Bold()
{
if (doc != null)
{
doc.execCommand("Bold", false, null);
}
}
}
该对象被设置为具有先前显示的按钮和样式的窗口的数据上下文。
如果你想看到我可以给你看的窗口代码,否则这里是button_click事件的代码
private void Button_Click(Object sender, RoutedEventArgs e)
{
Button button = e.Source as Button;
if (button != null)
{
this.AlterButtonStyle(button.Tag as String);
button.Style = (Style)(Window.GetWindow(button).TryFindResource("CurrentStyle"));
}
}
private void AlterButtonStyle(String propertyName)
{
if (String.IsNullOrWhiteSpace(propertyName)) return;
PropertyInfo info = this.formatting.GetType().GetProperty(propertyName);
if (info == null || info.PropertyType != typeof(Boolean)) return;
info.SetValue(this.formatting, !(Boolean)info.GetValue(this.formatting, null), null);
}
Button_Click事件中显示的"CurrentStyle"
在布尔属性中基于True或False更改
希望有所帮助。
谢谢!
答案 0 :(得分:2)
由于您只能在DependencyProperties上设置绑定,并且Binding对象的Path
属性不是DependencyProperty
,因此您无法在此处实现此类事情。
在您的情况下,我强烈建议您使用自定义附加属性。 (这是一种可以附加到任何对象的DependencyProperty,而不仅仅是特定的对象)
例如:
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(local:CustomProperties.DefaultButtonTriggerProperty)}"
Value="True">
// setters here
</DataTrigger>
</DataTemplate.Triggers>
和
<Button local:CustomProperties.DefaultButtonTriggerProperty="IsBold"
Style="{StaticResource DefaultButton}" ... />
它还具有额外的优势,允许您为您的属性提供一个描述性名称,让其他开发人员明白该属性的用途及其使用方式。我在这里使用了DefaultButtonTriggerProperty
,但如果可以的话,我会建议更具描述性的内容。
答案 1 :(得分:0)
你不能为每个数据触发器编写一个样式然后指向那个样式吗?