寻找更好的方法来编写复杂的 WPF UI

发布于 2024-10-14 11:21:27 字数 1253 浏览 1 评论 0原文

我继承的 WPF 应用程序包含大量 XAML,这些 XAML 遵循如下模式:

<Window ...>
    <Grid>
        <z:SomeUserControl>
            <z:AnotherUc>
                <Label /> <Button /> <ComboBox />
            </z:AnotherUc>
            <z:AnotherUc>
                <Label /> <Button /> <ComboBox />
            </z:AnotherUc>
        </z:SomeUserControl>
    </Grid>
</Window>

换句话说,我们有按 UserControl 分组的 UI 部分,通常嵌套在其他 UserControl 内。在某些时候,内容是使用基本 WPF 内容控件定义的。

我们试图解决的问题是,由于臭名昭著的 WPF 限制,x:Name 属性无法应用于任何最内部的控件:

无法设置元素 {1} 上的名称属性值 {0}。 {1} 位于元素 {2} 的范围内,该元素在另一个范围中定义时已注册了名称

这会带来一个问题,因为代码隐藏需要能够引用 UserControls 中的元素。选择 UserControls 来对 UI 的各个部分进行分组,因为默认控件的所有样式和模板都太笨重,而且标记很快就变成了可怕的、难以阅读的混乱。

然而,如果微软无意解决这个所谓的“限制”,那么就必须找到更好的方法。已考虑使用 CS + 外部 XAML 模板文件,如连接站点上的 GaryGJohnson 的解决方法所示。然而,这有一种意大利面条的感觉,任何中断绑定的东西都是不允许的。

The WPF application I've inherited contains a significant amount of XAML which follows a pattern like:

<Window ...>
    <Grid>
        <z:SomeUserControl>
            <z:AnotherUc>
                <Label /> <Button /> <ComboBox />
            </z:AnotherUc>
            <z:AnotherUc>
                <Label /> <Button /> <ComboBox />
            </z:AnotherUc>
        </z:SomeUserControl>
    </Grid>
</Window>

In other words, we have UI sections grouped by UserControl, often nested inside other UserControls. At some point, the content is defined using basic WPF content controls.

The problem we're trying to cope with is that the x:Name attribute cannot be applied to any of the inner most controls due to the infamous WPF limitation:

Cannot set Name attribute value {0} on element {1}. {1} is under the scope of element {2}, which already had a name registered when it was defined in another scope

This presents a problem because the code-behind needs to be able to reference elements within the UserControls. UserControls were selected to group parts of the UI because all the styling and templating of default controls because too unwielding and the markup quickly turned in to a horrible, unreadable mess.

However, if Microsoft has no intention of resolving this so-called "limitation," a better way must be found. Considering has been placed in using CS + external XAML template file as seen in GaryGJohnson's work-around on the connect site. However this has a feeling of sphagetti and anything that interrupts bindings is a no-go.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我很坚强 2024-10-21 11:21:27

这里最好的选择通常是避免在这些“内部”元素上使用隐藏代码。您仍然可以使用数据绑定,因此将这些绑定到 DataContext 中的属性将正常工作。

当然,另一种选择是直接将 Label/Button/ComboBox 公开为 AnotherUc 类的依赖属性。这将允许您直接将它们用作 UserControl 的成员,从而避免了范围问题。

当然,这样做的缺点是您必须为特定的元素组合自定义用户控件,而不是允许在其中放置任何控件。

The best option here is typically to avoid using code behind on those "inner" elements. You can still use data binding, so binding these to properties in your DataContext will work properly.

The other alternative, of course, is to expose the Label/Button/ComboBox directly as Dependency Properties of the AnotherUc class. This would allow you to usen them directly as members of the UserControl, which avoids the scoping issue.

The downside to this, of course, is that you must customize the user control for a specific combination of elements, instead of allowing any controls to be placed within it.

分开我的手 2024-10-21 11:21:27

听起来设计上很混乱。您可以创建自己的 AttachedProperty - MyNameProperty,在 XAML 中设置它并编写您自己的逻辑/可视树帮助器,这将起作用。我并不是说我会这样做,但如果您需要一个快速的解决方法(无需对 UI 组合模型进行彻底的重新设计),那么这可能会满足您的要求。

Sounds like a mess by design. You can create your own AttachedProperty - MyNameProperty, set it in your XAML and write your own Logical/Visual tree helper, which'll work of it. I'm not saying I would do that, but if you need a quick workaround (w/out radical redesign of you UI composition model), that may do you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文