0

カスタムUserControlのターゲットのDependencyPropertyが変更されたときに、バインディングソースが更新されないようになりました。

ソースは、MEFがカスタムUserControlのDataContextにロードされたViewModelです。

MyUserControlのルートXAMLでは、バインディングは次のようになります。

// MyUserControl.xaml
<MyUserControlBase x:Class="MyUserControl" MyDependencyProperty="{Binding ViewModelProperty}">

FrameworkPropertyMetadataでMyDependencyPropertyを使用し、プロパティが変更されたときにコールバック関数を使用すると、次のことができます。これは正常に機能します。

// MyUserControlBase.cs
private static void MyDependencyProperty_Changed(DependencyObject depObj, DependencyPropertyChangedEventArgs args)
{
    var filter = (UserControl )depObj;
    var vm = (ViewModel)filter.DataContext;
    vm.ViewModelProperty= (VMPropType)args.NewValue;
}

UserControlを継承するMyUserControlBaseへのDependencyPropertyの登録。

// MyUserControlBase.cs
public static readonly DependencyProperty MyDependencyPropertyProperty = DependencyProperty.Register("MyDependencyProperty",
            typeof(VMPropType),
            typeof(MyUserControlBase),
            new FrameworkPropertyMetadata(null, MyDependencyProperty_Changed));

しかし、XAMLで実行したときに、単純な双方向バインディングを機能させることができないのはなぜですか?

出力ウィンドウには、バインディングの失敗は表示されません。ViewModel.ViewModelPropertyゲッターが呼び出されていることがわかります。MyDependencyPropertyが変更されると、セッターではありません。

イベントの順序に問題はないようです。ViewModelは、DependencyPropertyが初めて変更されるずっと前に作成されます。

WPFユーザーコントロール内のカスタムDependencyPropertyへのバインドの設定も確認しましたが 、実際にはDependencyPropertyを保持する独自のBaseクラスから継承しているため、彼の問題は少し異なっているようです。

助けてくれてありがとう。

編集:ソリューション例へのリンク付き。 ここでソリューションzip

恐ろしいリンクで申し訳ありませんが、私は多くのクイックファイル共有サイトを知りません。その悪い投稿コメントと私はそれをできるだけ早く削除しますが、それは大丈夫のようです。

4

2 に答える 2

0

回答が更新されました/無関係な情報が削除されました

サンプルのコードを見た後、私は問題が何であるかを見ました。この「セレクター」コントロールがあります。このBindDependenciesメソッドでは、にバインディングを設定しますMyControlBase.MyDependencyProperty。ただし、同時に、このプロパティをコントロールのデータコンテキスト(内MyUserControl.xaml)にバインドします。事実上、これは、ビューモデルへのバインディングを上書きBindDependenciesしているため、そのメソッドの後でアクティブにならないことを意味します-呼び出しの前後に侵入して呼び出すことで、これを自分で確認できます-バインディングは異なります。これが、コードが機能しない理由です。そこに値を転送する別の方法を見つける必要があると思います:)SetBindingBindingOperations.GetBindingExpression(control, MyUserControlBase.MyPropertyDependencyProperty)

いくつかの追加情報

WPFでは、プロパティを1つのバインディングのみのターゲットにすることができます。これは実際には非常に論理的です-プロパティが2つのソースにバインドされている場合-どちらを使用する必要がありますか?バインディングがとしてマークされているという事実はOneWayToSource、コントロールのプロパティを対象とするバインディングとしてカウントされるため、この状況では実際には重要ではありません。

調査して、それが機能するかどうかを確認する1つの方法は、MultiBindingです。これにより、独自のを実装することで、コントロールのプロパティを複数のソースにバインドできますIMultiValueConverter。これに関する詳細は、MSDNの提供されたリンクにあります。

于 2012-07-23T12:47:56.503 に答える
0

ViewModelPropertyを通常のプロパティとして公開しますか。

通常、次のことを行います。

public static readonly DependencyProperty ViewModelPropertyProperty = DependencyProperty.Register("ViewModelProperty", 
            typeof(VMPropType), 
            typeof(MyUserControlBase), 
            new FrameworkPropertyMetadata(null, ViewModelProperty_Changed)); 

public VMPropType ViewModelProperty {
    get { return (VMPropType)GetValue(ViewModelPropertyProperty); }
    set { SetValue(ViewModelPropertyProperty,value); }
}

編集-コメントの後。

プロパティが変更されたことをいつ確認しますか?既定では、WPFバインディングは、フォーカスを失ったときにのみ値を更新します。この動作を変更するには、バインディングのUpdateSourceTriggerプロパティを変更します。

于 2012-07-23T13:15:08.333 に答える