【问题标题】:WPF bindable dependency property is not workingWPF 可绑定依赖属性不起作用
【发布时间】:2015-02-05 13:32:13
【问题描述】:

我绑定如下:

views:SciChartUserControl Name="SciChartUserControl" Quotes="{Binding QuoteCollection}"></views:SciChartUserControl>

我确定 QuoteCollection 会更新,因为网格也绑定到它并且我看到它已更新。我希望在我的 SciChartUserControl 视图的代码隐藏中得到通知,但永远不会调用 QuotesPropertyChanged。这让我发疯了,我已经尝试了几个小时的不同方式......我忽略了什么明显的东西?

public partial class SciChartUserControl : UserControl
{
    private SciChartControlViewModel _viewModel;

    public SciChartUserControl()
    {

        //Set ViewModel Datacontext
        _viewModel = new SciChartControlViewModel();
        DataContext = _viewModel;

        InitializeComponent();
    }

    public static DependencyProperty QuotesProperty = DependencyProperty.Register("Quotes", typeof(List<Quote>), typeof(SciChartUserControl), new PropertyMetadata(QuotesPropertyChanged));

    public List<Quote> Quotes
    {
        get
        {
            return (List<Quote>)GetValue(QuotesProperty);
        }

        set
        {
            SetValue(QuotesProperty, value);
        }
    }

    private static void QuotesPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        throw new NotImplementedException();

        var quotes = (List<Quote>) e.NewValue;
    }



}

编辑:我添加了托管SciChartUserControl 的部分视图。

 <dxdo:LayoutPanel Caption="Time Series Visualization">

                        <views:SciChartUserControl Name="SciChartUserControl" Quotes="{Binding QuoteCollection}"></views:SciChartUserControl>

                    </dxdo:LayoutPanel>

                    <dxdo:LayoutPanel Caption="Time Series Data">
                        <dxg:GridControl Name="SampleDataGridControl" ItemsSource="{Binding QuoteCollection}" AutoGenerateColumns="AddNew" EnableSmartColumnsGeneration="True" AutoGeneratedColumns="SampleDataGridControl_OnAutoGeneratedColumns">
                            <dxg:GridControl.View>
                                <dxg:TableView AllowEditing="False" AutoWidth="True" BestFitArea="All" AllowBestFit="True" ShowGroupPanel="True" ShowSearchPanelMode="Always"/>
                            </dxg:GridControl.View>
                        </dxg:GridControl>
                    </dxdo:LayoutPanel>

【问题讨论】:

  • 那么QuoteCollectionSciChartControlViewModel类的属性,是在SciChartControlViewModel构造函数中初始化的?您也可以向我们展示 SciChartControlViewModel 代码。
  • 不,我将 SciChartControl 托管在不同的 WPF UserControl 中。 viewmodel 实际上包含一个 QuoteCollection。我编辑了我的问题并添加了部分视图以显示另一个控件也绑定到 QuoteCollection 并且更新得很好。
  • 但是不要在 SciChartUserControl 的构造函数中设置 DataContext。这会覆盖从父控件继承的 DataContext。
  • 我需要访问视图模型,因为它应该作用于更新的Quotes。我还能如何访问视图模型?
  • 当您说您将 SciChartControl 托管在不同的 WPF UserControl 中时,我的假设是 DataContext(包含视图模型对象)由该外部控件继承。不然你为什么要告诉我们?无论如何,这里似乎不是这样。

标签: c# wpf binding dependency-properties


【解决方案1】:

尝试为PropertyMetadata 类使用另一个构造函数:

public static DependencyProperty QuotesProperty = DependencyProperty.Register("Quotes", 
    typeof(List<Quote>), typeof(SciChartUserControl), 
    new PropertyMetadata(someDefaultvalue, QuotesPropertyChanged));

可能是您正在使用的采用 PropertyChangedCallback 对象的单参数构造函数与采用单个 object 参数的构造函数混淆了。

【讨论】:

  • 哈,你成功了。但这怎么可能?我想了解为什么这会产生重大影响
  • 这只有在我没有在我的代码隐藏中设置数据上下文时才有效。但是我无法在我的视图模型中反映更新的QuoteCollection。如何解决这个问题?谢谢。
  • 这是可能的,因为一个构造函数期待PropertyChangedCallback 类型的对象,而另一个期待object 类型的对象之一。编译器尝试将您的调用映射到正确的构造函数,但由于您的 QuotesPropertyChanged 方法实际上不是 PropertyChangedCallback 对象,因此它选择了单个 object 默认值参数构造函数,因此您有一个默认值方法。这是微软的糟糕编程,而不是你的。
  • 该怎么做?...尝试使用RelativeSource Binding,而不是设置DataContext
  • @Sheridan 为什么 QuotesPropertyChanged 不应该是 PropertyChangedCallback?它有正确的签名。我从未注意到我的编译器在编写new PropertyMetadata(CallbackMethod) 时不会选择正确的PropertyMetadata 构造函数。
【解决方案2】:

试试这个... 在依赖属性声明中将 PropertyMetadata 更改为以下内容..

new PropertyMetadata(null, new PropertyChangedCallback(QuotesPropertyChanged))

【讨论】:

    【解决方案3】:

    我相信这是因为您在后面的代码中设置了 DataContext,我在 XAML 中设置时遇到了同样的问题?似乎 DependencyProperty 是相对于 UserControl 的 DataContext 绑定的。 UserControl's DependencyProperty is null when UserControl has a DataContext

    <views:SciChartUserControl Name="SciChartUserControl"
                               Quotes="{Binding DataContext.QuoteCollection, RelativeSource={RelativeSource AncestorType={x:Type dxdo:LayoutPanel}}}" />
    

    【讨论】:

    • “似乎 DependencyProperty 被绑定到相对于 UserControl 的 DataContext”。什么?当然它会这样做,除非您明确设置绑定的 Source 或 RelativeSource。这正是 DataContext 属性的用途。
    • @Clemens 你是正确的(显然),这就是手头的问题(imo)和我的解决方案解决的问题。然而,我不觉得这似乎是普遍理解的。作为证据,我的问题被否决并且两周没有收到答案?当然,社区知道我们可以将 UserControl 中的元素相对于 UserControl 的 DataContext 绑定,例如TextBox 的 Text 属性将相对于它继承的 DataContext 进行绑定。我们较少做的是绑定到 UserControl 本身的属性。
    猜你喜欢
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 2012-06-24
    • 2012-11-08
    • 1970-01-01
    • 2014-08-31
    • 2023-03-26
    • 2013-03-06
    相关资源
    最近更新 更多