52

View -> ViewModel 解決のために Cinch (したがって MefedMVVM) を利用する、標準の MVVM パターンを持つ WPF アプリケーションがあります。これはうまく機能し、関連するコントロールを ViewModel のプロパティにバインドできます。

特定のビュー内に、Infragistics XamGrid があります。このグリッドは、ViewModel の ObservableCollection にバインドされ、適切な行を表示します。ただし、このグリッドには、ObservableCollection ではなく、親 DataContext のプロパティに TextBox テキスト値をバインドしようとしている特定の列があります。このバインディングは失敗しています。

ここでは、次のようないくつかのオプションを検討しました。

  1. AncestorType を使用してツリーを追跡し、親 UserControl の DataContext にバインドします (この質問への優れた回答とこの質問から) ...

    {Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
    
  2. ElementName を指定し、最上位のコントロールを直接ターゲットにしようとしています。ElementName の使用について読みたい場合は、こちらをご覧ください。

  3. UserControl のリソースで定義された「プロキシ」FrameorkElement を使用して、必要に応じてコンテキストを「渡します」。以下のように要素を定義し、静的リソースとして参照します...

    <FrameworkElement x:Key="ProxyContext" DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource Self}}"></FrameworkElement>
    

この場合、バインディングは FrameworkElement を見つけますが、それを超えるものにはアクセスできません (パスを指定する場合)。

いろいろ読んだところ、これは Infragistics XamGrid がツリーの外側に列を構築していることが原因である可能性が非常に高いようです。ただし、その場合でも、少なくともオプション 2 または 3 は機能するはずです。

私たちの最後の考えでは、これは V - VM バインディングに関連しているということですが、Snoop を使用しても、正確な問題が何であるかはまだわかっていません。私は決して WPF バインディングの専門家ではないので、ポインタをいただければ幸いです。

編集: Infragistics hereからいくつかのテンプレートの例を見つけたので、試してみます。

編集 2: @Dtex で指摘されているように、テンプレートが最適です。XamGrid で使用する関連スニペットは次のとおりです。

<ig:GroupColumn Key="CurrentDate">
                <ig:GroupColumn.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=DataContext.CurrentDateTest, RelativeSource={RelativeSource AncestorType=UserControl}}" />
                    </DataTemplate>
                </ig:GroupColumn.HeaderTemplate>
                <ig:GroupColumn.Columns>

XML を開いたままにしておきます...必要な列を追加してから、関連するタグを閉じます。

4

2 に答える 2

96

私は知りXamGridませんが、それは私が標準の wpf で行うことですDataGrid:

<DataGrid>
    <DataGrid.Columns>
        <DataGridTemplateColumn>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <TextBlock Text="{Binding DataContext.MyProperty, RelativeSource={RelativeSource AncestorType=MyUserControl}}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
            <DataGridTemplateColumn.CellEditingTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding DataContext.MyProperty, RelativeSource={RelativeSource AncestorType=MyUserControl}}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellEditingTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

セル テンプレートで指定されたTextBlockTextBoxはビジュアル ツリーの一部になるため、上に移動して必要なコントロールを見つけることができます。

于 2012-11-16T13:15:16.580 に答える
0

このようなことから、一般的な経験則として、私は XAML の「トリッキー」をできるだけ避け、XAML をできるだけ馬鹿げた単純なものに保ち、残りを ViewModel (または添付プロパティまたは IValueConverters など) で行うようにしています。本当に必要な場合)。

可能であれば、現在の DataContext の ViewModel に、関連する親 ViewModel への参照 (つまり、プロパティ) を与えます。

public class ThisViewModel : ViewModelBase
{
    TypeOfAncestorViewModel Parent { get; set; }
}

代わりにそれに対して直接バインドします。

<TextBox Text="{Binding Parent}" />

于 2012-11-16T11:39:54.670 に答える