如何使用 XAML 样式模板绑定到另一个对象 属性?
How to bind to another's object property with XAML Style Template?
假设我有以下 class:
public class MyClass : System.Windows.FrameworkElement
{
public static readonly DependencyProperty HasFocusProperty = DependencyProperty.RegisterAttached("HasFocus", typeof(bool), typeof(MyClass), new PropertyMetadata(default(bool)));
public bool HasFocus
{
get => (bool)GetValue(HasFocusProperty);
set => SetValue(HasFocusProperty, value);
}
public System.Windows.Controls.TextBox TextBox { get; set; }
}
我想通过基于 属性 HasFocus
的 XAML 模板触发器更改 TextBox
的某些 UI 属性,因此我执行以下操作:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:win="clr-namespace:System.Windows.Controls">
<Style TargetType="{x:Type win:TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type win:TextBox}">
<ControlTemplate.Triggers>
<Trigger Property="MyClass.HasFocus" Value="True">
<Setter TargetName="Border" Property="BorderBrush" Value="Red" />
<Setter TargetName="Border" Property="BorderThickness" Value="2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
但是,设置HasFocus = true
时没有应用样式。
在 TextBox
的属性中,我可以看到触发器已注册。如果我将 <Trigger Property="MyClass.HasFocus" Value="True">
更改为 <Trigger Property="MyClass.HasFocus" Value="False">
,则会首先应用我的样式。所以我认为我的 XAML 定义没问题。
有什么解决办法吗?
应用于 TextBox
的模板中的元素不能绑定到 MyClass
的 属性,除非有 MyClass
元素可以绑定在视觉树的某处。
如果您希望能够设置 TextBox
的自定义 HasFocus
属性,您应该创建一个 attached property:
public class FocusExtensions
{
public static readonly DependencyProperty SetHasFocusProperty = DependencyProperty.RegisterAttached(
"HasFocus",
typeof(bool),
typeof(FocusExtensions),
new FrameworkPropertyMetadata(false)
);
public static void SetHasFocus(TextBox element, bool value)
{
element.SetValue(SetHasFocusProperty, value);
}
public static bool GetHasFocus(TextBox element)
{
return (bool)element.GetValue(SetHasFocusProperty);
}
}
可以为任何 TextBox
元素设置:
<TextBox local:FocusExtensions.HasFocus="True">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="local:FocusExtensions.HasFocus" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="2" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
假设我有以下 class:
public class MyClass : System.Windows.FrameworkElement
{
public static readonly DependencyProperty HasFocusProperty = DependencyProperty.RegisterAttached("HasFocus", typeof(bool), typeof(MyClass), new PropertyMetadata(default(bool)));
public bool HasFocus
{
get => (bool)GetValue(HasFocusProperty);
set => SetValue(HasFocusProperty, value);
}
public System.Windows.Controls.TextBox TextBox { get; set; }
}
我想通过基于 属性 HasFocus
的 XAML 模板触发器更改 TextBox
的某些 UI 属性,因此我执行以下操作:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:win="clr-namespace:System.Windows.Controls">
<Style TargetType="{x:Type win:TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type win:TextBox}">
<ControlTemplate.Triggers>
<Trigger Property="MyClass.HasFocus" Value="True">
<Setter TargetName="Border" Property="BorderBrush" Value="Red" />
<Setter TargetName="Border" Property="BorderThickness" Value="2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
但是,设置HasFocus = true
时没有应用样式。
在 TextBox
的属性中,我可以看到触发器已注册。如果我将 <Trigger Property="MyClass.HasFocus" Value="True">
更改为 <Trigger Property="MyClass.HasFocus" Value="False">
,则会首先应用我的样式。所以我认为我的 XAML 定义没问题。
有什么解决办法吗?
应用于 TextBox
的模板中的元素不能绑定到 MyClass
的 属性,除非有 MyClass
元素可以绑定在视觉树的某处。
如果您希望能够设置 TextBox
的自定义 HasFocus
属性,您应该创建一个 attached property:
public class FocusExtensions
{
public static readonly DependencyProperty SetHasFocusProperty = DependencyProperty.RegisterAttached(
"HasFocus",
typeof(bool),
typeof(FocusExtensions),
new FrameworkPropertyMetadata(false)
);
public static void SetHasFocus(TextBox element, bool value)
{
element.SetValue(SetHasFocusProperty, value);
}
public static bool GetHasFocus(TextBox element)
{
return (bool)element.GetValue(SetHasFocusProperty);
}
}
可以为任何 TextBox
元素设置:
<TextBox local:FocusExtensions.HasFocus="True">
<TextBox.Style>
<Style TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="local:FocusExtensions.HasFocus" Value="True">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="2" />
</Trigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>