我正在尝试创建一个类,该类将管理基于不同对象集合的输入的对象集合。生成的集合特定于我的用户界面,而输入集合只是数据对象(模型)的集合。
我希望能够将输入集合绑定到我的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:在我的建议之后我将数据绑定输出的详细程度一直提升,这是我使用间谍得到的:
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,它可以在没有间谍的情况下工作,但如果我不继承freezable,即使使用DataContextSpy也不行。我不确定在这种情况下我是否需要间谍。是否可以在没有我的GraphPlotManager继承freezable的情况下工作?
答案 0 :(得分:0)
继承自Freezable而不是DepedencyObject允许我在UserControl.Resources中声明我的GraphPlotManager,并能够使用Bindings和ElementName Bindings。
Leveraging Freezables to Provide an Inheritance Context for Bindings
我知道这个技巧,但我想我大多数时候都看过它关于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;
}
}