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:ウィルの提案の後、データバインディング出力の冗長性を完全に上げました。スパイを使用して得たものは次のとおりです。

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 を継承せずに動作することは可能ですか?

4

1 に答える 1

0

DepedencyObject の代わりに Freezable から継承することで、UserControl.Resources で GraphPlotManager を宣言し、Bindings と ElementName Bindings を使用できるようになりました。

Freezable を利用してバインディングの継承コンテキストを提供する

私はこのトリックについて知っていましたが、ContextMenus ま​​たは ToolTips に関してほとんど見たことがあり、このシナリオに適している可能性があることに実際には気づいていませんでした。

私が見つけたもう 1 つの便利なクラスは、ブレークポイントを DataBinding に配置して、いつ起動し、値が何であるかを調べることができる IValueConverter でした。

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 に答える