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

时间:2011-01-24 17:42:58

标签: wpf xaml user-controls

我继承的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的感觉,任何中断绑定的东西都是禁止的。

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:1)

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