1

3 つのチェックボックスと 3 つの日付ピッカーを含むユーザー コントロールがあります。たとえば、ユーザー コントロールの日付ピッカーの 1 つは次のようになります (明確にするために、幅などの無関係なプロパティは削除されています)...

<telerik:RadDatePicker DisplayFormat="Long"
                       SelectedValue="{Binding DepositPaidDate, Mode=TwoWay}"/>

コントロールのビュー モデルには、PaidDate 型の PaidDate というパブリック プロパティがあり (そうです、プロパティとクラスは同じ名前です)、コントロールの最上位の Grid には、その DataContext が PaidDate プロパティに設定されています。 Grid 内の個々のコントロールは、この PaidDate オブジェクトのプロパティにバインドされます。

このコントロールがウィンドウで使用され、ウィンドウのコード ビハインドがコントロールの VM に明示的に PaidDate プロパティを設定すると、すべて正常に動作します。たとえば、コンストラクターが次のようなテストウィンドウを作成しました...

public PaidDateWindow(PaidDate paidDate, string windowTitle) {
  InitializeComponent();
  ((PaidDateControlViewModel)PaidDateCtrl.DataContext).PaidDate = paidDate;
  Title = windowTitle;
}

...そして、これはうまくいきました。ウィンドウを表示でき、データが正しく表示されました。

コントロールの依存関係プロパティを介してこれを設定しようとすると、問題が発生します。ユーザー コントロールのコード ビハインドの依存関係プロパティは次のようになります...

public static readonly DependencyProperty PaidDateProperty = DependencyProperty.Register("PaidDate", typeof(PaidDate), typeof(PaidDateControl), new FrameworkPropertyMetadata(SetPaidDateStatic));

private static void SetPaidDateStatic(DependencyObject d, DependencyPropertyChangedEventArgs e) {
  (d as PaidDateControl).SetPaidDate((PaidDate)e.NewValue);
}

private void SetPaidDate(PaidDate paidDate) {
  if (DataContext != null) {
    ((PaidDateControlViewModel)DataContext).PaidDate = paidDate;
  }
}

public PaidDate PaidDate {
  get {
    return (PaidDate)GetValue(PaidDateProperty);
  }
  set {
    SetValue(PaidDateProperty, value);
  }
}

ご覧のとおり、依存関係プロパティは PaidDate オブジェクトをビュー モデルに渡すだけで、前のコードで手動で行ったときと同じ効果があります。

この依存関係プロパティをウィンドウのビュー モデルのプロパティにバインドしようとすると、バインド エラーが発生します。親ウィンドウの XAML は次のとおりです...

<vrtSystemsUserControls:PaidDateControl
  PaidDate="{Binding Path=VRTSystem.PaidDate, Mode=TwoWay}" />

親ウィンドウの VM には VrtSystem と呼ばれるプロパティが含まれており、ウィンドウ上の他の多くのコントロールがそのプロパティにバインドされています。VrtSystem には PaidDate というプロパティも含まれており、これをユーザー コントロールに渡したいと考えています。

ただし、これを実行すると、次のバインディングエラーが発生します...

System.Windows.Data Error: 40 : BindingExpression path error:
'VRTSystem' property not found on 'object' ''PaidDateControlViewModel' (HashCode=18319327)'.
BindingExpression:Path=VRTSystem.PaidDate; DataItem='PaidDateControlViewModel' (HashCode=18319327);
target element is 'PaidDateControl' (Name=''); target property is 'PaidDate' (type 'PaidDate')

ユーザーコントロールのVMでVrtSystemプロパティを見つけようとしているというエラーが表示されるため、PaidDateオブジェクトではなく、WPFが実際のバインディング情報をユーザーコントロールに渡しているように見えます。バインディングのアイデアは、ウィンドウ レベルでバインディングを解決し、結果 (つまり、PaidDate オブジェクト) を依存関係プロパティに送信することだと思っていたので、なぜそれが行われるのかわかりません。 VM に送信されます。

これを明確に説明できたことを願っています。何がうまくいかなかったのかわかる人はいますか?

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

4

1 に答える 1

2

バインディングが解決されると、バインディングが適用されているコントロールのVRTSystemプロパティが検索されます。DataContext

'DataContext' プロパティは子コントロールによって継承されているため、 を に設定するDataContextと、Windowそのすべての子に同じ が設定されますDataContext。ただし、子の 1 つ自体に別の DataContext が適用されている場合、そのすべての子はそれを使用します。

あなたの場合、 にはWindowがありますDataContextが、 もありUserControlます。したがって、デフォルトでは、UserControlまたはそのチルレンのすべてのバインディングは、この場合に必要なものではないのVRTSystemプロパティを見つけることを期待します。UserControls DataContext

したがって、 の を明示的にターゲットにするDataContextには、次のようにプロパティWindowを設定してバインディングに通知する必要があります。RelativeSource

{Binding Path=DataContext.VRTSystem.PaidDate, Mode=TwoWay,
         RelativeSource={RelativeSource AncestorType={x:Type Window}}}
于 2013-01-30T17:14:14.223 に答える