C# 如何使用ContentTemplate避免;指定的元素已经是另一个元素的逻辑子元素。“先断开它的连接”;错误
我知道这个问题被问了无数次,但我不明白他们的问题是什么,也不知道如何效仿他们。 我确实找到了她的名字Rachel,她在博客上写了这个名字,但是她的解释太简短了 以下是我在尝试遵循以下示例之前所做的:C# 如何使用ContentTemplate避免;指定的元素已经是另一个元素的逻辑子元素。“先断开它的连接”;错误,c#,.net,wpf,devexpress,C#,.net,Wpf,Devexpress,我知道这个问题被问了无数次,但我不明白他们的问题是什么,也不知道如何效仿他们。 我确实找到了她的名字Rachel,她在博客上写了这个名字,但是她的解释太简短了 以下是我在尝试遵循以下示例之前所做的: <Window x:Class="Graph.View.MainView.Main" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.micro
<Window x:Class="Graph.View.MainView.Main"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
Title="Main" Height="350" Width="525"
xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking">
<DockPanel LastChildFill="True">
<DockPanel>
<Label Content="{Binding ScreenContent}" Grid.Row="1" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch"/>
</DockPanel>
</DockPanel>
我怎样才能修好它?它没有显示任何东西。。。
谢谢。请回答我什么是
ScreenContent
属性。。。是绳子吗?还是一些GUI元素
如果是字符串,则按照下面的解决方案进行操作…
还有一些你必须理解的概念
Label
内部Label
是一个糟糕的UI设计内容控件
如标签
,按钮
等。当我们想要设置它们的控制模板
和数据模板
时,遵循特定的XAML模式ScreenContent
。因此,DataTemplate
方法是正确的数据模板内的标签
,因为外部标签
(您已将样式
应用到该标签)本身的内容
属性未设置
因此基本上是ContentControl.ContentTemplate
只有在ContentControl
上和DataTemplate
(ContentTemplate
)内设置了非空Content
的情况下才能工作Content
作为所有项目的DataContext
强>
注意下面的{Binding}
表达式。。。这是不言自明的
<DockPanel LastChildFill="True">
<DockPanel.Resources>
<Style x:Key="MyCustomContentControl"
TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<DockPanel>
<ContentPresenter
Content="{Binding}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</DockPanel>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
</DockPanel.Resources>
<Label Style="{StaticResource MyCustomContentControl}"
Content="{Binding ScreenContent}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
</Label>
</DockPanel>
你的主机面板应该是这样的
<DataTemplate x:Key="MyTitleControlDataTemplate">
<local:TitleControl Title="{Binding MyTitle}"/>
</DataTemplate>
<ContentControl ToolTip="Title is shown here..."
Content="{Binding MyTitleControlViewModel}"
Contenttemplate="{StatiocResource MyTitleControlDataTemplate}"/>
<ContentControl ToolTip="Same title control is shown here also !!!"
Content="{Binding MyTitleControlViewModel}"
Contenttemplate="{StatiocResource MyTitleControlDataTemplate}"/>
因此,通过这种方式,相同的标题控件似乎托管在上面的两个内容控件上。但是如果你真的这么想的话,有两个不同的TitleControl
实例,它们仅仅表示相同的MyTitleControlViewModel
,因此看起来像一个相同的控件
谷歌搜索数据模板、MVVM的组合方式。如果您想重用屏幕内容(尽管它已经是其他元素的子元素),那么您必须首先克隆它并使用克隆的控件
您可以先使用XamlWriter
对控件进行序列化,然后使用XamlReader
对其进行反序列化,从而克隆控件,类似于-
在窗口中使用此screenContentClone
但是,您可能会发现自己正在应用变通方法以使其正常工作,因为在使用XamlWriter.Save
(与绑定类似)时存在一些限制
下面是其他一些序列化方法-
尽管您的设计不像AngelWPF提到的那样正确,您应该尝试重新设计您的窗口,并且您可能不需要这样做。用户控件(或任何其他类型的UI控件)不属于视图模型
最好有一个绑定到的对象,并使用DataTemplate
告诉WPF如何使用UserControl
绘制该对象
例如,如果你有
ScreenModel ScreenContent { get; set; }
其中,ScreenModel
是一个定制类,看起来像这样
public class ScreenModel
{
public string Name { get; set; }
...
}
然后,您可以使用如下方式绑定到它:
<DockPanel LastChildFill="True">
<DockPanel>
<ContentControl Content="{Binding ScreenContent}" Grid.Row="1" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch"/>
</DockPanel>
</DockPanel>
或
由于您使用的是模板
,WPF将在需要时创建用户控件
的新副本,并且不会尝试在多个位置使用相同的用户控件
发生错误的原因是您通过Content=“{Binding ScreenContent}”
绑定多次向VisualTree
添加相同的UserControl
(ScreenContent
)
即使是切换选项卡之类的操作也可能会导致此错误,因为您将通过切换离开选项卡来卸载所有UI对象,然后通过切换回来加载新的UI对象,但是,您的ScreenContent
用户控件已将其父控件设置为不再存在的旧对象。如果要将其用作该键的静态资源,至少应设置
。这不起作用:(ScreenContent是一个用户控件。我将它分配给一个标签内容,我认为这样做是可以的,但当然我不能重用该用户控件(screen)还有。我还以为这个方法会奏效!是的,但两种情况都不同。但假设你有一个选项卡式用户控件。在主选项卡中,你有一个EmployeeUserControl实例,只要你在第二个选项卡中没有另一个EmployeeUserControl实例,实际上它不会让你创建一个新的EmployeeUserControl来执行操作作为第二个选项卡。我想我知道问题是什么,但不知道如何解决它。我基本上是将构成屏幕的部分代码复制到Subscreen视图中。我删除了绑定,因为它将显示静态数据。但我一时兴起,决定重用我拥有的ViewModel。当我使用ViewModel时,即使SubscreennView没有任何逻辑父级。因此,这里的ViewModel是原因,为什么?我不知道。我认为您在做一些根本错误的事情!ViewModel
和ContentControls
与DataTemplate
提供的原因完全相同,以便在多个实例中显示类似的控件。您能提供您的答案吗urce code?@Lewsterin您已将此问题标记为DevXPress!您是否使用任何DevXPress控件?如何使用?更简单的方法是使用另一个UserControl。我希望重用视图,以便随时可以制作小屏幕。这一限制很糟糕。无论如何,谢谢。我认为这里没有任何限制!
public class ScreenModel
{
public string Name { get; set; }
...
}
<DockPanel LastChildFill="True">
<DockPanel>
<ContentControl Content="{Binding ScreenContent}" Grid.Row="1" HorizontalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" VerticalContentAlignment="Stretch"/>
</DockPanel>
</DockPanel>
<DataTemplate DataType="{x:Type models:ScreenModel}">
<views:ScreenContentUserControl />
</DataTemplate>
<DataTemplate DataType="{x:Type models:ScreenModel}">
<Label Content="{Binding Name}" />
</DataTemplate>