Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf ContentControl内部绑定不起作用_Wpf_Binding - Fatal编程技术网

Wpf ContentControl内部绑定不起作用

Wpf ContentControl内部绑定不起作用,wpf,binding,Wpf,Binding,我正在建立一个图形设计师,基于一个。我现在尝试扩展它,以便画布上的每个项目都绑定到不同的ViewModel对象,也就是说,我正在为每个项目设置DataContext 设计器中的每个项实际上都是一个ContentControl,其中放置了一个不同的模板(基于将工具箱项拖到画布上的模板)。所以我有一个包含TextBox的模板,还有一个包含Name属性的ViewModel对象,我将TextBox的Text属性绑定到ViewModel的Name属性,然后。。。没有什么。我已经用Snoop检查了可视化树,

我正在建立一个图形设计师,基于一个。我现在尝试扩展它,以便画布上的每个项目都绑定到不同的ViewModel对象,也就是说,我正在为每个项目设置DataContext

设计器中的每个项实际上都是一个ContentControl,其中放置了一个不同的模板(基于将工具箱项拖到画布上的模板)。所以我有一个包含TextBox的模板,还有一个包含Name属性的ViewModel对象,我将TextBox的Text属性绑定到ViewModel的Name属性,然后。。。没有什么。我已经用Snoop检查了可视化树,它确认TextBox的DataContext是ViewModel对象。然而文本框仍然是空的。如果修改文本框中的(空)文本,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属性。那么为什么文本框仍然是空的呢?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;