具有依赖属性绑定到 DockPanel.Dock 附加属性的 WPF 自定义控件不起作用
Posted
技术标签:
【中文标题】具有依赖属性绑定到 DockPanel.Dock 附加属性的 WPF 自定义控件不起作用【英文标题】:WPF Custom Control with Dependency Property binding to DockPanel.Dock Attached Property not working 【发布时间】:2013-10-09 16:24:05 【问题描述】:我正在尝试创建一个具有 4 种状态(上、下、左、右)的自定义控件,这些状态中的每一个都需要更新 DockPanel.Dock 附加属性,该属性附加到控件模板中的 Image 控件.
我的部分控件模板如下:
<ControlTemplate TargetType="x:Type library:IndicatorButton">
<DockPanel LastChildFill="True">
<Image x:Name="Icon"
DockPanel.Dock="TemplateBinding State" Height="66" Width="87"
HorizontalAlignment="Center" VerticalAlignment="Center"
Stretch="UniformToFill" Source="DynamicResource HandIcon"/>
<Border Background="x:Null"
BorderBrush="TemplateBinding BorderBrush"
BorderThickness="TemplateBinding BorderThickness"
SnapsToDevicePixels="True" >
<Rectangle Fill="Transparent"/>
</Border>
并且“State”属性被定义为像这样的依赖属性
public static readonly DependencyProperty StateProperty =
DependencyProperty.Register("State", typeof(HandIndicatorStates),
typeof(IndicatorButton),
new FrameworkPropertyMetadata(HandIndicatorStates.None,
OnIndicatorStateChanged)
BindsTwoWayByDefault = true,
);
HandIndicatorStates 是一个枚举,定义如下
public enum HandIndicatorStates
Left = 0,
Right = 1,
Top = 2,
Bottom = 3,
None = 4
最后我像这样在 xaml 中定义控件
<library:IndicatorButton State="Top" BorderBrush="Yellow" BorderThickness="5"/>
当我更改控件定义中的“State”属性时,没有任何反应。但是当我删除控件模板中的模板绑定并将其替换为“顶部”、“底部”等时,我得到了所需的结果。
我确定这不是我应该在自定义控件代码中做的事情。我省略了一些内容以尽量保持简短和甜蜜,但如果您需要其他任何内容,请询问
感谢您的帮助
【问题讨论】:
状态是否在开始时正确设置,即在您的问题中您已将状态设置为顶部,它是否在开始时设置在图像上? 我猜是因为您的 DP 需要使用类型Dock,而您将其设置为类型HandIndicatorStates
,无法转换为Dock
值
【参考方案1】:
好吧,DockPanel.Dock
附加属性是 System.Windows.Controls.Dock 类型,而您要绑定的属性是您自己的自定义枚举类型。
这是行不通的,您应该在 Visual Studio 的输出窗口中收到一个绑定错误,表明这一点。
要使其工作,您可以将IValueConverter
附加到绑定,它只是在不同枚举类型之间进行映射。
我编写了一个非常小的程序来展示它是如何完成的。没有ControlTemplate
或类似的东西,但你的与实际问题无关。
public partial class MainWindow : Window
public MainWindow()
InitializeComponent();
DataContext = this;
public HandIndicatorStates State
get return HandIndicatorStates.Top;
public enum HandIndicatorStates
Left = 0,
Right = 1,
Top = 2,
Bottom = 3,
None = 4
public class StateToDockEnumConverter : IValueConverter
public object Convert(object value, Type targetType,
object parameter, System.Globalization.CultureInfo culture)
HandIndicatorStates state = (HandIndicatorStates)value;
if (state == HandIndicatorStates.None)
return null; //??
// Map from HandIndicatorStates to Dock enum by name.
var dock = Enum.Parse(typeof(Dock), state.ToString());
return dock;
public object ConvertBack(object value,
Type targetType, object parameter,
System.Globalization.CultureInfo culture)
throw new NotImplementedException();
还有 XAML:
<Window.Resources>
<local:StateToDockEnumConverter x:Key="conv" />
</Window.Resources>
<DockPanel>
<Button Content="Dock to top"
DockPanel.Dock="Binding State, Converter=StaticResource conv" />
<Button Content="Fill rest" />
</DockPanel>
【讨论】:
谢谢!对自己没有弄清楚这一点有点失望。我想我会把它归结为昨天的日志日以上是关于具有依赖属性绑定到 DockPanel.Dock 附加属性的 WPF 自定义控件不起作用的主要内容,如果未能解决你的问题,请参考以下文章
WPF编程,我上层容器是dockpanel,里边想放3个canvas,但是实际的效果是后边的canvas会占满整个窗口,怎么办