自定义控件绑定设置器不触发

时间:2020-02-20 17:48:33

标签: c# wpf

我有一个带有以下代码的自定义控件:

public partial class TableSelectorControl : UserControl
{
    private Brush _cellHoverBrush = new SolidColorBrush(Colors.CadetBlue) { Opacity = 0.3 };

    public static readonly DependencyProperty ActiveSelectionProperty =
        DependencyProperty.Register("ActiveSelection", typeof(TableSelectorSelection),
            typeof(TableSelectorControl));

    public TableSelectorSelection ActiveSelection
    {
        get => (TableSelectorSelection)GetValue(ActiveSelectionProperty);
        set 
        {
            SetValue(ActiveSelectionProperty, value);
            _cellHoverBrush = value.HoverBrush;
        }
    }
}

如您所见,我正在尝试在每个_cellHoverBrush更新中设置ActiveSelectionProperty,这是通过ViewModel完成的。绑定工作良好,并且ActiveSelectionProperty似乎已更改,但设置器未触发。我当然可以使用FrameworkProperyMetadata,但我不希望_cellHoverBrush成为static,其想法是针对选定的ActiveSelection进行更改。我该如何实现?

如果需要,我可以提供更多信息。

2 个答案:

答案 0 :(得分:2)

WPF中有两种类型的属性:.NET Framework属性和依赖项属性(它们特定于WPF)。每个依赖项属性都有一个.Net Framework属性,但是此属性只是WPF依赖项属性的包装。这样做是为了标准化我们在WPF中使用属性的方式。在从.xaml文件的绑定中使用依赖项属性时,WPF框架将不会使用.Net包装器属性来获取或设置值。这就是为什么未指示在.NET包装属性中使用除GetValueSetValue之外的其他代码的原因。

对于所需内容,应使用 PropertyChangedCallback ,如以下示例所示:

public partial class TableSelectorControl : UserControl
{
    private Brush _cellHoverBrush = new SolidColorBrush(Colors.CadetBlue) { Opacity = 0.3 };

    public static readonly DependencyProperty ActiveSelectionProperty =
        DependencyProperty.Register("ActiveSelection", typeof(TableSelectorSelection),
            typeof(TableSelectorControl), new PropertyMetadata(new PropertyChangedCallback(OnActiveSelectionChanged)));

    public TableSelectorSelection ActiveSelection
    {
        get => (TableSelectorSelection)GetValue(ActiveSelectionProperty);
        set => SetValue(ActiveSelectionProperty, value);
    }

    private static void OnActiveSelectionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var tableSelCtrl = d as TableSelectorControl;
        if (tableSelCtrl != null)
        {
            tableSelCtrl._cellHoverBrush = (e.NewValue as TableSelectorSelection)?.HoverBrush;
        }
    }
}

答案 1 :(得分:1)

使用FrameworkPropertyMetadata的PropertyChangedCallback并不一定意味着您需要将字段设为静态。您的处理程序方法将获得对正在调用它的实例的引用,然后您可以对其进行修改-但您需要首先将其强制转换为您的类型。

此页面上的PropertyChanged演练显示了一种可能的方法。 https://docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/dependency-property-callbacks-and-validation

相关问题