Wpf ContentControl内部绑定不起作用
我正在建立一个图形设计师,基于一个。我现在尝试扩展它,以便画布上的每个项目都绑定到不同的ViewModel对象,也就是说,我正在为每个项目设置DataContext 设计器中的每个项实际上都是一个ContentControl,其中放置了一个不同的模板(基于将工具箱项拖到画布上的模板)。所以我有一个包含TextBox的模板,还有一个包含Name属性的ViewModel对象,我将TextBox的Text属性绑定到ViewModel的Name属性,然后。。。没有什么。我已经用Snoop检查了可视化树,它确认TextBox的DataContext是ViewModel对象。然而文本框仍然是空的。如果修改文本框中的(空)文本,ViewModel中的Name属性不会更改。所以看起来绑定没有被应用(或者以某种方式被删除) 我发现有几篇文章讨论了ContentControl与DataContext和Content属性的混淆,但我不确定它们是否都适用。代码将ContentControl.Content设置为:Wpf ContentControl内部绑定不起作用,wpf,binding,Wpf,Binding,我正在建立一个图形设计师,基于一个。我现在尝试扩展它,以便画布上的每个项目都绑定到不同的ViewModel对象,也就是说,我正在为每个项目设置DataContext 设计器中的每个项实际上都是一个ContentControl,其中放置了一个不同的模板(基于将工具箱项拖到画布上的模板)。所以我有一个包含TextBox的模板,还有一个包含Name属性的ViewModel对象,我将TextBox的Text属性绑定到ViewModel的Name属性,然后。。。没有什么。我已经用Snoop检查了可视化树,
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属性。那么为什么文本框仍然是空的呢?Snoop允许我更改该Name属性,但文本框仍然为空
我做错了什么
还有一些细节。我已经将OutputWindow的VS2010调试数据绑定选项设置为Verbose,这似乎表明在设置DataContext之前,正在尝试所有绑定。是否可能无法识别对DataContext的更改
我刚刚发现这篇文章-显然DataTemplate.LoadContent不保留绑定。因此,看起来我必须编写自己版本的LoadContent()
我意识到该模板是通过一个XamlWriter实现的,它显然会剥离所有绑定。这没用
我无法修复DataTemplate.LoadContent(),但我意识到我实际上并不需要DataTemplate,因为XamlWriter/XamlReader已经在实例化我所关注的UI元素。我找到了一个修复方法,让XamlWriter编写所有绑定,然后一切正常
谢谢您的帮助。也许您需要告诉
控制模板中的绑定查看模板客户端,如中所述
或者,或者尝试使用DataTemplate
我现在无法测试这一点,所以我可能只是在这里猜测。我会使用数据模板,正如bde建议的那样
您正试图在自己的数据(ViewModel)上放置一些UI,这就是数据模板的用途(ControlTemplate
通常是您想要使用的)
将代码更改为使用ContentControl.ContentTemplate
和DataTemplate
:
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Width="100">
<TextBox Text={Binding Name}/>
</Border>
</DataTemplate>
谢谢你的建议,但那没用。我还尝试将DataContext绑定到ContentControl中的元素,Snoop shows将其绑定到TextBox,但这也不起作用。所有这些的困难在于我不知道如何调试这个绑定问题。我可以使用Snoop看到TextBox的DataContext是正确的,但我不知道如何找出绑定不绑定的原因-没有引发异常,输出窗口中也没有任何内容。剩下的似乎只是随机尝试各种不同类型的绑定参数。是的,在WPF中调试绑定问题并不容易。除了VS中的输出
窗口(有时会显示绑定错误消息)之外,我不知道有什么工具可以帮助实现这一点。如果您无法使控件模板正常工作,您可能必须使用数据模板
。感谢您的建议-这很有意义,所以我已经这样做了,但没有什么区别。Snoops显示文本框具有正确的DataContext,但名称仍不显示。还有其他想法吗?如何在toolbox.GetTemplate()
中加载模板?您也可以发布该函数吗?GetTemplate()只是一个常规的附加属性,即:公共静态只读DependencyProperty DesignerElementProperty=DependencyProperty.RegisterAttached(“DesignerElement”、typeof(FrameworkElement)、typeof(DesignerItem));公共静态FrameworkElement GetDesignerElement(UIElement元素){Object value=element.GetValue(DesignerElementProperty);return(FrameworkElement)value;}
这是一些DesignerElement
属性的代码,而不是GetTemplate()
方法。我不确定我是否理解您的解决方案,但通过阅读您更新的问题,我发现您已经解决了它,所以我想这一切都很好:)
<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;