0

我正在尝试创建一个类,该类将管理基于不同对象集合的输入的对象集合。生成的集合特定于我的用户界面,而输入集合只是数据对象(模型)的集合。

我希望能够将输入集合绑定到我的 DataContext 的属性。因此,在 XAML 中而不是在后面的代码中似乎会很好。我尝试实现 DepedencyObject 并为输入集合创建一个 DP。我还在我的 GraphPlotManager 依赖对象中实现了 IEnumerable,因此我可以将其他控件项源绑定到它。

我试过这个:

<local:GraphPlotManager x:Key="plotManager"
                                 GraphObjects="{Binding GraphObjects}">

并使用 DataContextSpy

<common:DataContextSpy x:Key="spy2" />
<local:GraphPlotManager x:Key="plotManager"
                                 GraphObjects="{Binding Source={StaticResource spy2}, Path=DataContext.GraphObjects}" />

我的绘图管理器的构造函数被调用,但从不设置或修改依赖属性,并且输出窗口中没有显示任何错误。是什么赋予了?

编辑:这是 DP 代码(我使用了代码片段,只添加了一个 OnChanged 处理程序)

public ObservableCollection<GraphObjectViewModel> GraphObjects
{
    get { return (ObservableCollection<GraphObjectViewModel>)GetValue(GraphObjectsProperty); }
    set { SetValue(GraphObjectsProperty, value); }
}

public static readonly DependencyProperty GraphObjectsProperty =
    DependencyProperty.Register("GraphObjects", typeof(ObservableCollection<GraphObjectViewModel>), typeof(GraphPlotManager), new UIPropertyMetadata(null, OnGraphObjectsChanged));

private static void OnGraphObjectsChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    // this code never gets hit and the Collection is still null as far as I can tell
}

Edit2:在 will 的建议之后,我将数据绑定输出的详细程度一直提高,这就是我使用间谍得到的结果:

System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=DataContext.GraphObjects; DataItem='DataContextSpy' (HashCode=44673241); target element is 'GraphPlotManager' (HashCode=565144); target property is 'GraphObjects' (type 'ObservableCollection`1')

更新:

如果我的经理从 Freezable 继承,它可以在没有间谍的情况下工作,但如果我不继承可冻结,即使使用 DataContextSpy 也不能。我不确定在这种情况下我是否需要间谍。如果我的 GraphPlotManager 没有继承可冻结,是否可以工作?

4

1 回答 1

0

从 Freezable 继承而不是 DepedencyObject 允许我在 UserControl.Resources 中声明我的 GraphPlotManager 并能够使用 Bindings 和 ElementName Bindings。

利用 Freezables 为绑定提供继承上下文

我知道这个技巧,但我想我主要是在 ContextMenus 或 ToolTips 方面看到它,并没有真正意识到它可能适合这种情况。

我发现的另一个有用的类是 IValueConverter,它允许您在 DataBindings 中放置断点,以检查它们何时触发以及值是什么。

public class DebugConverter : IValueConverter
{
    public static DebugConverter Instance = new DebugConverter();
    private DebugConverter() { }

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Debugger.Break();
        return value; //Binding.DoNothing;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        Debugger.Break();
        return value; //Binding.DoNothing;
    }

    #endregion
}

public class DebugExtension : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return DebugConverter.Instance;
    }
}

来源:在 WPF 中调试数据绑定问题

于 2012-11-01T21:30:20.780 回答