3

我正在根据Sukram 在 CodeProject 中的一篇文章构建一个图形设计器。我现在正在尝试扩展它,以便画布上的每个项目都绑定到不同的 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,我可以看到它有一个 Name 属性,其值为“Bob”。那么为什么 TextBox 仍然是空的呢?Snoop 允许我更改 Name 属性,但 TextBox 保持为空。

我究竟做错了什么?


还有一些细节。我已将 OutputWindow 的 VS2010 Debug DataBinding 选项设置为 Verbose,这似乎表明在我设置 DataContext之前已尝试进行所有绑定。是否可能无法识别对 DataContext 的更改?


我刚刚发现这篇文章DataTemplate.LoadContent 不保留绑定- 显然 DataTemplate.LoadContent 不保留绑定。所以看起来我必须编写自己的 LoadContent() 版本。


我已经意识到该模板是通过 XamlWriter 实现的,它显然剥离了所有绑定。这不会有帮助。


我无法修复 DataTemplate.LoadContent(),但我意识到我实际上并不需要 DataTemplate,因为 XamlWriter / XamlReader 已经在实例化我所追求的 UI 元素。我找到了一个修复程序,让 XamlWriter 在此处编写所有绑定,然后一切正常。

谢谢你的帮助。

4

2 回答 2

0

Maybe you need to tell the binding in the ControlTemplate to look at the TemplatedParent, as is mentioned in this thread?

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

Either that, or try to use a DataTemplate instead.

I can't test this at the moment, so I might just be guessing here.

于 2013-01-06T00:20:39.963 回答
0

DataTemplate正如 bde 建议的那样,我会使用 a 。

您正在尝试将一些 UI 放在您自己的数据(ViewModel)上,这就是Data -Templates 的用途(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 回答