You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Style中设置自定义依赖属性时绑定自身属性的问题

问题描述

我定义了名为PropertyPanel的自定义依赖属性,通过Style为infiniteReservoir:PressureSource类型设置该属性的值。我希望将PressureSource自身的属性(如Name、ToolTip)绑定到PropertyPanel内的对应控件,尝试使用RelativeSource={RelativeSource TemplatedParent}进行绑定,但无显示效果。请问是否需要使用ControlTemplate声明目标类型,或有其他解决方法?

相关代码如下:

ResourceDictionary 代码

<Style TargetType="{x:Type infiniteReservoir:PressureSource}">
 <Setter Property="PropertyPanel">
 <Setter.Value>
 <ScrollViewer >
 <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
 <Grid.ColumnDefinitions>
 <ColumnDefinition/>
 <ColumnDefinition/>
 </Grid.ColumnDefinitions>
 <Grid.RowDefinitions>
 <RowDefinition Height="30"/>
 <RowDefinition Height="30"/>
 <RowDefinition Height="30"/>
 <RowDefinition Height="30"/>
 <RowDefinition Height="30"/>
 <RowDefinition Height="30"/>
 </Grid.RowDefinitions>
 <TextBlock Text="Pressure:" Grid.Row="0"/>
 <Grid Grid.Column="1">
 <Grid.ColumnDefinitions>
 <ColumnDefinition Width="2*"/>
 <ColumnDefinition Width="*"/>
 </Grid.ColumnDefinitions>
 <TextBox/>
 <ComboBox Grid.Column="1"/>
 </Grid>
 <TextBlock Text="Temperature:" Grid.Row="1"/>
 <Grid Grid.Row="1" Grid.Column="1">
 <Grid.ColumnDefinitions>
 <ColumnDefinition Width="2*"/>
 <ColumnDefinition Width="*"/>
 </Grid.ColumnDefinitions>
 <TextBox/>
 <ComboBox Grid.Column="1"/>
 </Grid>
 <TextBlock Text="Label:" Grid.Row="2"/>
 <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Name}"/>
 <TextBlock Text="Media:" Grid.Row="3"/>
 <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding ToolTip}"/>
 <TextBlock Text="Fluid Zone ID:" Grid.Row="4"/>
 <TextBlock Grid.Row="4" Grid.Column="1"/>
 <TextBlock Text="Port Name:" Grid.Row="5"/>
 <TextBox Grid.Row="5" Grid.Column="1"/>
 </Grid>
 </ScrollViewer>
 </Setter.Value>
 </Setter>
</Style>

Model 代码

#region PropertyPanel
public ScrollViewer PropertyPanel {
 get { return (ScrollViewer)GetValue(PropertyPanelProperty); }
 set { SetValue(PropertyPanelProperty, value); }
}
public static readonly DependencyProperty PropertyPanelProperty = DependencyProperty.Register("PropertyPanel", typeof(ScrollViewer), typeof(DesignerItem));
#endregion

解决方案

你遇到的问题根源很明确:RelativeSource TemplatedParent只在ControlTemplate的内部有效,而你现在是直接把ScrollViewer作为PropertyPanel属性的Setter值,它并不是ControlTemplate的一部分,所以这个绑定根本找不到对应的父元素。

这里有两种可行的解决思路:

方法1:使用ControlTemplate(推荐)

如果PressureSource是Control的子类,这是最规范的解决方案。通过ControlTemplate定义它的可视化结构后,TemplatedParent就能正确指向PressureSource实例。修改方式如下:

  1. 把原来的ScrollViewer及内部结构移到ControlTemplate中
  2. 在Style中设置Template属性,若仍需保留PropertyPanel属性,可以通过绑定关联到内部的ScrollViewer

示例代码片段:

<Style TargetType="{x:Type infiniteReservoir:PressureSource}">
 <Setter Property="Template">
 <Setter.Value>
 <ControlTemplate TargetType="{x:Type infiniteReservoir:PressureSource}">
 <ScrollViewer x:Name="PropertyPanelHost">
 <Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
 <!-- 原有Grid内容,此时Name、ToolTip的绑定会正常生效 -->
 <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Name}"/>
 <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding ToolTip}"/>
 </Grid>
 </ScrollViewer>
 </ControlTemplate>
 </Setter.Value>
 </Setter>
 <!-- 绑定PropertyPanel属性到内部的ScrollViewer -->
 <Setter Property="PropertyPanel" Value="{Binding ElementName=PropertyPanelHost, RelativeSource={RelativeSource TemplatedParent}}"/>
</Style>

方法2:直接绑定到PressureSource实例(无需ControlTemplate)

如果不想重构为ControlTemplate,可以在设置PropertyPanel内容时,显式把DataContext绑定到当前的PressureSource对象。因为Style的Setter作用于每个PressureSource实例,所以用RelativeSource FindAncestor就能定位到目标:

修改ResourceDictionary中的Grid DataContext:

<ScrollViewer>
 <Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type infiniteReservoir:PressureSource}}}">
 <!-- 这里直接绑定Name、ToolTip即可,DataContext已指向PressureSource -->
 <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Name}"/>
 <TextBlock Grid.Row="3" Grid.Column="1" Text="{Binding ToolTip}"/>
 <!-- 其余原有控件保持不变 -->
 </Grid>
</ScrollViewer>

另外要注意:你的PropertyPanel依赖属性定义在DesignerItem类上,需要确保PressureSource是DesignerItem的子类,否则这个Setter会无法生效;如果不是子类,建议把PropertyPanelProperty移到PressureSource类中。


内容的提问来源于stack exchange,提问作者Yekta Mirkan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:03:42