WPF - CAL - 单个控件实例的多个父级?
我正在开发一种 PRISM / CAL 解决方案,但问题可能是 WPF 特定的:
如果我创建一个控件实例(例如 TextBlock)并将其作为子项添加到 StackPanel,则无法将其添加为“子项”到另一个 StackPanel(父级已设置错误)。我有点理解原因(使用 RegionManager 时也会发生)。
但是,如果视觉控件非常复杂并且应该仅创建一次并在两个地方使用,那么建议的方法是什么?我同意在屏幕上显示相同的控件两次并没有真正意义,但在某些情况下它可能很有用(例如“关闭全部”按钮)。
我知道在按钮的情况下,我应该只创建两个按钮,两个按钮都数据绑定到一个 ICommand。但是这个规则是否也适用于更复杂的控件(总是创建新实例)...
我在创建布局切换器时偶然发现了这个问题,它为每个 GUI 分别创建按钮列表和堆栈面板,但使用静态 ObservableCollection按钮作为源(这会导致奇怪的错误)..
关于这个主题有什么想法吗?
克里斯
I am working on a PRISM / CAL solution, but the problem may be WPF specific:
If I create one instance of an control (e.g. TextBlock) and add it as child to a StackPanel, there is no way to add it as "child" to another StackPanel (parent already set error). I kind of understand the reason (it also occurs when using the RegionManager).
But what is the suggested way if a visual control is very complex and should be created only one time and used in two places? I agree that is does not really make sense to show an identical control 2 times on the screen, but there might be cases where it is useful (e.g. an "Close All" Button).
I know that in the button case, I should just create two buttons both databound to one ICommand. But does this rule also apply with much more complex controls (always create new instances)...
I stumbled on this problem when creating a layout switcher, which creates the button list and the stack panel for each GUI seperately, but uses a static ObservableCollection of buttons as source (which causes strange bugs)..
Any ideas on this topic?
Chris
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这通常由模板处理。也就是说,您将数据抽象为特定类型,并将模板与该类型相关联。然后,将该数据的实例多次放入可视化树中,并让 WPF 使用模板渲染它。
简而言之,不要将
TextBlock
添加到StackPanel
中。相反,添加数据类型的实例(例如Customer
)并将DataTemplate
与Customer
类型关联。无法在多个位置为同一个UIElement
指定父级。This is normally handled by templates. That is, you abstract out the data into a particular type, and associate a template with that type. Then you place the instance of that data any number of times into your visual tree and have WPF render it with the template.
In short, don't add a
TextBlock
to yourStackPanel
. Instead, add an instance of your data type (eg.Customer
) and associate aDataTemplate
with theCustomer
type. There is no way to parent the sameUIElement
in multiple places.您可以将控件(或控件集合)添加为资源,并通过控件中的绑定来引用它们。这将隐式创建一个副本(它们将是 Freezable 并且 WPF 将复制它们)。
一般来说,您应该按照 Kent 的建议使用 DataTemplates,但如果您有特殊情况,这可能会起作用。
You can add your control (or collection of controls) as a resource and refer to them via binding in your controls. This will implicitly create a copy (they will be Freezable and WPF will copy them).
Generally you should be using DataTemplates as Kent suggests, but if you have a special case, this will likely work.