【问题标题】:Finding a better way to write complex WPF UIs寻找编写复杂 WPF UI 的更好方法
【发布时间】:2011-01-25 04:02:44
【问题描述】:

我继承的 WPF 应用程序包含大量 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 属性不能应用于任何最内部的控件:

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

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

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

【问题讨论】:

  • 我遇到了类似的问题,我使用了 CustomControl 项。但现在我知道一切都可以使用 MVVM 和行为来完成。所以我尽量避免使用 x:Name 属性。

标签: wpf xaml user-controls


【解决方案1】:

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

当然,另一种选择是将标签/按钮/组合框直接公开为AnotherUc 类的依赖属性。这将允许您直接将它们用作 UserControl 的成员,从而避免范围问题。

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

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 如果您可以发布一些松散的 xaml,我可以分享我的想法。您在上面发布的那个看起来像是 ItemsControl 的一个很好的候选者 - 即具有公共 UI 元素的重复项可以被视为 ItemsControl 项。
    猜你喜欢
    • 1970-01-01
    • 2020-09-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-13
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    相关资源
    最近更新 更多