3

CodeProject の Sukramの記事に基づいて、グラフィカル デザイナーを構築しています。キャンバス上の各アイテムが異なる ViewModel オブジェクトにバインドされるように拡張しようとしています。つまり、各アイテムの DataContext を設定しています。

デザイナのすべてのアイテムは実際には ContentControl であり、その中に別のテンプレートが配置されます (どのツールボックス アイテムがキャンバスにドラッグされたかに基づいて)。したがって、TextBox を含むテンプレートがあり、Name プロパティを含む ViewModel オブジェクトがあり、TextBox の Text プロパティを ViewModel の Name プロパティにバインドしますが、何もありません。Snoop でビジュアル ツリーを確認したところ、TextBox の DataContext が ViewModel オブジェクトであることが確認されました。それでも、TextBox は空のままです。また、TextBox の (空の) Text を変更しても、ViewModel の Name プロパティは変更されません。そのため、バインディングが適用されていないようです (または、何らかの方法で削除されています)。

ContentControl が DataContext および Content プロパティをいじっているという記事をいくつか見つけましたが、それらすべてがどの程度当てはまるかはわかりません。このコードは、ContentControl.Content を次のように設定します。

newItem = new ContentControl();
ControlTemplate template = toolbox.GetTemplate();
UIElement element = template.LoadContent() as UIElement;
ViewModelItem viewModel = new ViewModelItem() { Name = "Bob" };

newItem.Content = element;
newItem.DataContext = viewModel;

テンプレートの XAML は次のとおりです。

<ControlTemplate>
    <Border BorderBrush="Black" BorderThickness="1" Width="100">
        <TextBox Text={Binding Name}/>
    </Border>
</ControlTemplate>

Snoop は、TextBox に DataContext があることを示しています。その DataContext を詳しく調べると、値が「Bob」である Name プロパティがあることがわかります。では、なぜ TextBox は空のままなのでしょうか? Snoop を使用すると、その Name プロパティを変更できますが、TextBox は空のままです。

私は何を間違っていますか?


さらにいくつかの詳細。OutputWindow の VS2010 Debug DataBinding オプションを Verboseに設定しました。これは、DataContext を設定する前にバインディングがすべて試行されていることを示しているようです。DataContext への変更が認識されていない可能性はありますか?


この投稿を見つけましたDataTemplate.LoadContent does not preserve bindings - どうやら DataTemplate.LoadContent はバインディングを保持しません。そのため、独自のバージョンの LoadContent() を作成する必要があるようです。


テンプレートが XamlWriter を経由していることに気付きました。XamlWriter は明らかにすべてのバインドを取り除きます。これは役に立ちません。


DataTemplate.LoadContent() を修正できませんでしたが、XamlWriter / XamlReader が目的の UI 要素を既にインスタンス化していたため、実際には DataTemplate は必要ないことに気付きました。XamlWriter がすべてのバインディングをここに書き込むようにするための修正が見つかりました。その後、すべてが機能します。

ご協力いただきありがとうございます。

4

2 に答える 2

0

DataTemplatebde が示唆するように、私は a を使用します。

独自のデータ(ViewModel)にいくつかの UI を配置しようとしていますが、これがData -Templates の目的です (たとえば、 a の外観を変更ControlTemplateする場合は通常、これを使用します)。Button

ContentControl.ContentTemplateで使用するようにコードを変更しますDataTemplate

<DataTemplate>
    <Border BorderBrush="Black" BorderThickness="1" Width="100">
        <TextBox Text={Binding Name}/>
    </Border>
</DataTemplate>

分離コード:

newItem = new ContentControl();
//NOTE: .GetTemplate() needs to return a DataTemplate, and not a ControlTemplate:
newItem.ContentTemplate = toolbox.GetTemplate();

ViewModelItem viewModel = new ViewModelItem() { Name = "Bob" };

newItem.Content = viewModel;
newItem.DataContext = viewModel;
于 2013-01-06T15:41:10.807 に答える
0

このスレッドで言及されているように、 のバインディングにControlTemplateを参照するように指示する必要があるかもしれません。TemplatedParent

<TextBox Text="{Binding Path=Name, RelativeSource={RelativeSource TemplatedParent}}"/>

それか、DataTemplate代わりに a を使用してみてください。

現時点でこれをテストすることはできないので、ここで推測するだけかもしれません。

于 2013-01-06T00:20:39.963 に答える