1. ホーム
  2. wpf

[解決済み] DataTemplateから親DataContextにアクセスする

2022-08-23 18:56:46

質問

私は ListBox があり、ViewModel 上の子コレクションにバインドされています。リストボックスの項目は、親 ViewModel のプロパティに基づいて datatemplate でスタイルが設定されます。

<Style x:Key="curveSpeedNonConstantParameterCell">
   <Style.Triggers>
      <DataTrigger Binding="{Binding Path=DataContext.CurveSpeedMustBeSpecified, 
          ElementName=someParentElementWithReferenceToRootDataContext}" 
          Value="True">
          <Setter Property="Control.Visibility" Value="Hidden"></Setter>
      </DataTrigger>
   </Style.Triggers>
</Style>

以下のような出力エラーが出ます。

System.Windows.Data Error: 39 : BindingExpression path error: 
 'CurveSpeedMustBeSpecified' property not found on 
   'object' ''BindingListCollectionView' (HashCode=20467555)'. 
 BindingExpression:Path=DataContext.CurveSpeedMustBeSpecified; 
 DataItem='Grid' (Name='nonConstantCurveParametersGrid');
 target element is 'TextBox' (Name=''); 
 target property is 'NoTarget' (type 'Object')

ということで、バインド式を "Path=DataContext.CurrentItem.CurveSpeedMustBeSpecified" に変更すると動作しますが、これは親ユーザーコントロールのデータコンテキストが BindingListCollectionView . のプロパティにバインドされるため、これは受け入れられません。 CurrentItem のプロパティにバインドされるからである。 BindingList を自動生成します。

親データ コンテキストがコレクション ビューであるか単一項目であるかに関係なく動作するように、スタイル内でバインド式を指定するにはどうすればよいですか。

どのように解決するのですか?

私はSilverlightの相対的なソースで問題がありました。検索して読んだ後、私はいくつかの追加のバインディング ライブラリを使用せずに適切な解決策を見つけることができませんでした。しかし、ここにあります。 親DataContextにアクセスするための別の方法です。 のように、データコンテキストを知っている要素を直接参照することで、親データコンテキストにアクセスすることができます。これは Binding ElementName を使用し、独自の命名法を尊重し templates / styles コンポーネントをまたいで

<ItemsControl x:Name="level1Lister" ItemsSource={Binding MyLevel1List}>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Button Content={Binding MyLevel2Property}
              Command={Binding ElementName=level1Lister,
                       Path=DataContext.MyLevel1Command}
              CommandParameter={Binding MyLevel2Property}>
      </Button>
    <DataTemplate>
  <ItemsControl.ItemTemplate>
</ItemsControl>

これは、ボタンを Style / Template :

<Border.Resources>
  <Style x:Key="buttonStyle" TargetType="Button">
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="Button">
          <Button Command={Binding ElementName=level1Lister,
                                   Path=DataContext.MyLevel1Command}
                  CommandParameter={Binding MyLevel2Property}>
               <ContentPresenter/>
          </Button>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>
</Border.Resources>

<ItemsControl x:Name="level1Lister" ItemsSource={Binding MyLevel1List}>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <Button Content="{Binding MyLevel2Property}" 
              Style="{StaticResource buttonStyle}"/>
    <DataTemplate>
  <ItemsControl.ItemTemplate>
</ItemsControl>

最初、私は x:Names はテンプレート化されたアイテム内からはアクセスできないのではと思いましたが、他に良い解決策がなかったので試してみたところ、問題なく動作しました。