C# 如何绑定到Style.Resource中的附加属性?
我正在尝试使用附加属性在文本框的背景中创建提示文本标签,但无法解析与样式资源中文本标题的绑定: 样式定义:C# 如何绑定到Style.Resource中的附加属性?,c#,.net,wpf,xaml,C#,.net,Wpf,Xaml,我正在尝试使用附加属性在文本框的背景中创建提示文本标签,但无法解析与样式资源中文本标题的绑定: 样式定义: <Style x:Key="CueBannerTextBoxStyle" TargetType="TextBox"> <Style.Resources> <VisualBrush x:Key="CueBannerBrush" AlignmentX="Left" Ali
<Style x:Key="CueBannerTextBoxStyle"
TargetType="TextBox">
<Style.Resources>
<VisualBrush x:Key="CueBannerBrush"
AlignmentX="Left"
AlignmentY="Center"
Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding Path=(EnhancedControls:CueBannerTextBox.Caption), RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}"
Foreground="LightGray"
Background="White"
Width="200" />
</VisualBrush.Visual>
</VisualBrush>
</Style.Resources>
<Style.Triggers>
<Trigger Property="Text"
Value="{x:Static sys:String.Empty}">
<Setter Property="Background"
Value="{DynamicResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text"
Value="{x:Null}">
<Setter Property="Background"
Value="{DynamicResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused"
Value="True">
<Setter Property="Background"
Value="White" />
</Trigger>
</Style.Triggers>
</Style>
用法:
<TextBox x:Name="txtProductInterfaceStorageId"
EnhancedControls:CueBannerTextBox.Caption="myCustomCaption"
Width="200"
Margin="5"
Style="{StaticResource CueBannerTextBoxStyle}" />
其思想是,您可以在创建文本框时定义视觉画笔中使用的文本提示,但我得到一个绑定错误:
System.Windows.Data错误:4:找不到用于绑定的源,引用为“RelativeSource FindAncestor,AncestorType='System.Windows.Controls.TextBox',AncestorLevel='1'。BindingExpression:路径=(0);DataItem=null;目标元素为“标签”(名称=“”);目标属性为“内容”(类型为“对象”)
如果我只是在样式中硬编码Label.Content属性,代码就可以正常工作
有什么想法吗?这里的问题与样式
的工作方式有关:基本上,将创建一个样式
的“副本”(在第一次引用时),在这一点上,可能有多个文本框
控件要将此样式
应用到-它将用于哪个相对资源
(可能的)答案是使用模板
而不是样式
——通过控件或数据模板,您将能够访问模板属性的可视化树
,这将帮助您找到需要的位置
编辑:进一步考虑,我可能不正确……当我回到电脑前时,我会准备一个快速测试工具,看看我是否能证明/反驳这一点
进一步编辑:虽然我最初说的可以说是“真实的”,但这不是你的问题;劳尔所说的:视觉树是正确的:
- 您正在将
上的TextBox
属性设置为Background
实例VisualBrush
- 该画笔的
未映射到控件的视觉树中视觉
- 因此,任何
导航将失败,因为该视觉的父项将为空{RelativeSource FindAncestor}
- 无论是声明为
还是样式
,情况都是如此控制模板
- 尽管如此,依赖
显然是不理想的,因为它降低了定义的可重用性ElementName
<Style x:Key="CueBannerTextBoxStyle"
TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="TextBox.Text"
Value="{x:Static sys:String.Empty}">
<Setter Property="local:HackyMess.Background">
<Setter.Value>
<VisualBrush AlignmentX="Left"
AlignmentY="Center"
Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding Path=(local:HackyMess.Caption)}"
Foreground="LightGray"
Background="White"
Width="200" />
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsKeyboardFocused"
Value="True">
<Setter Property="local:HackyMess.Background"
Value="White" />
</Trigger>
</Style.Triggers>
</Style>
<TextBox x:Name="txtProductInterfaceStorageId"
local:HackyMess.Caption="myCustomCaption"
local:HackyMess.Context="{Binding RelativeSource={RelativeSource Self}}"
Width="200"
Margin="5"
Style="{StaticResource CueBannerTextBoxStyle}" />
<TextBox x:Name="txtProductInterfaceStorageId2"
local:HackyMess.Caption="myCustomCaption2"
local:HackyMess.Context="{Binding RelativeSource={RelativeSource Self}}"
Width="200"
Margin="5"
Style="{StaticResource CueBannerTextBoxStyle}" />
问题在于
可视化笔刷中的标签
不是文本框
的可视子项,这就是绑定不起作用的原因。我的解决方案是使用ElementName
绑定。但是您正在创建的可视笔刷位于样式
的字典资源中,然后元素名称
绑定将无法工作,因为找不到元素id。解决方法是在全局字典资源中创建可视笔刷
。查看此XAML代码了解VisualBrush
:
<Window.Resources>
<VisualBrush x:Key="CueBannerBrush"
AlignmentX="Left"
AlignmentY="Center"
Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding Path=(EnhancedControls:CueBannerTextBox.Caption), ElementName=txtProductInterfaceStorageId}"
Foreground="#4F48DD"
Background="#B72121"
Width="200"
Height="200" />
</VisualBrush.Visual>
</VisualBrush>
<Style x:Key="CueBannerTextBoxStyle"
TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Text"
Value="{x:Static System:String.Empty}">
<Setter Property="Background"
Value="{DynamicResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text"
Value="{x:Null}">
<Setter Property="Background"
Value="{DynamicResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused"
Value="True">
<Setter Property="Background"
Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
这段代码应该有效。没有更多的代码需要更改,所以我不会重写所有的代码
希望这个解决方案对你有用 看起来它只是将元素名硬编码到样式中-如何重用?我只能有一个文本框使用此解决方案?好的,我会尝试-让我知道如果你成功!谢谢
<Style x:Key="CueBannerTextBoxStyle"
TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="TextBox.Text"
Value="{x:Static sys:String.Empty}">
<Setter Property="local:HackyMess.Background">
<Setter.Value>
<VisualBrush AlignmentX="Left"
AlignmentY="Center"
Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding Path=(local:HackyMess.Caption)}"
Foreground="LightGray"
Background="White"
Width="200" />
</VisualBrush.Visual>
</VisualBrush>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="IsKeyboardFocused"
Value="True">
<Setter Property="local:HackyMess.Background"
Value="White" />
</Trigger>
</Style.Triggers>
</Style>
<TextBox x:Name="txtProductInterfaceStorageId"
local:HackyMess.Caption="myCustomCaption"
local:HackyMess.Context="{Binding RelativeSource={RelativeSource Self}}"
Width="200"
Margin="5"
Style="{StaticResource CueBannerTextBoxStyle}" />
<TextBox x:Name="txtProductInterfaceStorageId2"
local:HackyMess.Caption="myCustomCaption2"
local:HackyMess.Context="{Binding RelativeSource={RelativeSource Self}}"
Width="200"
Margin="5"
Style="{StaticResource CueBannerTextBoxStyle}" />
<Window.Resources>
<VisualBrush x:Key="CueBannerBrush"
AlignmentX="Left"
AlignmentY="Center"
Stretch="None">
<VisualBrush.Visual>
<Label Content="{Binding Path=(EnhancedControls:CueBannerTextBox.Caption), ElementName=txtProductInterfaceStorageId}"
Foreground="#4F48DD"
Background="#B72121"
Width="200"
Height="200" />
</VisualBrush.Visual>
</VisualBrush>
<Style x:Key="CueBannerTextBoxStyle"
TargetType="{x:Type TextBox}">
<Style.Triggers>
<Trigger Property="Text"
Value="{x:Static System:String.Empty}">
<Setter Property="Background"
Value="{DynamicResource CueBannerBrush}" />
</Trigger>
<Trigger Property="Text"
Value="{x:Null}">
<Setter Property="Background"
Value="{DynamicResource CueBannerBrush}" />
</Trigger>
<Trigger Property="IsKeyboardFocused"
Value="True">
<Setter Property="Background"
Value="White" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>