具有绑定到 DockPanel 的依赖项属性的 WPF 自定义控件.Dock 附加属性不起作用
本文关键字:属性 WPF 自定义控件 不起作用 Dock 绑定 DockPanel 依赖 | 更新日期: 2023-09-27 18:34:32
我正在尝试创建一个具有 4 种状态(顶部、底部、左侧、右侧(的自定义控件,并且这些状态中的每一个都需要更新附加到控件模板中的 Image 控件的 DockPanel.Dock 附加属性。
我的控件模板的一部分如下所示:
<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"属性时,没有任何反应。但是当我删除控件模板中的模板绑定并将其替换为"顶部"、"底部"等时,我得到了所需的结果。
我确定这是我在自定义控件代码中没有做的事情。我省略了一些东西来尽量保持简短和甜蜜,但如果您需要其他任何东西,请询问
感谢您的任何帮助
好吧,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>