首页 > 解决方案 > 自定义控件中的属性绑定到依赖属性不起作用

问题描述

我创建了一个名为“ItemsPerPage”的带有 DependencyProperty 的自定义控件。我在一个窗口中使用了那个自定义控件。现在,如果我将值直接分配给 ItemsPerPage 属性,那么它可以工作,但是如果我将它与窗口中定义的属性绑定,那么它就无法工作。

海关控制声明。

public class SmartDataGrid : DataGrid
{

    public SmartDataGrid()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(SmartDataGrid), new FrameworkPropertyMetadata(typeof(SmartDataGrid)));
    }


    public static readonly DependencyProperty ItemsPerPageProperty =
       DependencyProperty.Register("ItemsPerPage", typeof(Int32),
           typeof(SmartDataGrid)
           , new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnItemsPerPageChanged, CoerceTextProperty, true, UpdateSourceTrigger.PropertyChanged));

    public Int32 ItemsPerPage
    {
        get
        {
            return (Int32)GetValue(ItemsPerPageProperty);
        }
        set
        {
            SetValue(ItemsPerPageProperty, value);
        }
    }

    private static void OnItemsPerPageChanged(DependencyObject defectImageControl, DependencyPropertyChangedEventArgs eventArgs)
    {
        var control = (SmartDataGrid)defectImageControl;
        control.callmyInstanceMethod(eventArgs);
    }

    private static object CoerceTextProperty(DependencyObject d, object value)
    {
        return value ?? 0;
    }
    private void callmyInstanceMethod(DependencyPropertyChangedEventArgs e)
    {
        ItemsPerPage = (Int32)e.NewValue;
    }
}

现在我创建了一个新的 WPF 项目,并在 Window1 中使用了这个自定义控件,如下所示。

<Grid>
        <sg:SmartDataGrid ItemsPerPage="{Binding ipp}"></sg:SmartDataGrid>
    </Grid>

这里 sg: 是一个命名空间,声明添加自定义控件项目的引用。在 Window1 的 .cs 文件中,我声明了一个属性。

public partial class Window1 : Window, INotifyPropertyChanged
{

    int _ipp;
    public int ipp
    { get { return _ipp; } set { _ipp = value; RaisePropertyChanged(); } }

    public Window1()
    {
        ipp = 30;
        InitializeComponent();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    public void RaisePropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

但是值 30 没有分配给 ItemsPerPage 属性。它总是显示0。如果我直接分配 30 ItemsPerPage="30"。然后它正在工作。

标签: c#wpfdata-bindingdependency-properties

解决方案


我认为 OP 的作者不想将 datacontext 设置为窗口。您需要将控件绑定到 Window 的属性,如下所示:

ItemsPerPage="{Binding Path=ipp,
                          RelativeSource={RelativeSource Mode=FindAncestor,
                                                         AncestorType=Window}}"

ipp 应通知属性已更改:

int _ipp;
public int ipp
{ 
   get=>_ipp;
   set{
        if (value!=_ipp)
        {
           _ipp=value;
           RaisePropertyChanged(nameof(ipp));
        }
   }
}
void RaisePropertyChanged(string propname)
{
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}


public Window1()
{
     ipp = 30;
     InitializeComponent();
}

推荐阅读