【问题标题】:Set property on the parent control from a data template从数据模板设置父控件的属性
【发布时间】:2011-05-20 22:19:02
【问题描述】:

如何从数据模板中设置父/祖先控件的属性?

我能想到的唯一方法是在我的表单上创建一个虚拟的不可见控件,然后使用转换器、onewaytosource 和 relativesource findancestor 绑定将其中一个属性与正确的默认值绑定,这是一个非常糟糕的解决方案。

我想要做的是能够让 setter 以不同的控件为目标,就像使用绑定到不同的源一样。

【问题讨论】:

    标签: wpf xaml


    【解决方案1】:

    几个可能的选项: 1)在DataTemplate内部的绑定上,使用ElementName将源设置为父级,并使用OneWayToSource进行绑定。这会将值从绑定目标(DataTemplate 中的元素)传输到绑定源(父控件) 2) 使用 DataTemplate 和控件都绑定到的公共对象。 DataTemplate 将使用 OneWayToSource 绑定到它,控件将使用 OneWay 绑定到它。它甚至可以是一种资源,因此您可以从 XAML 访问它。 3) 使用RelativeSource 和FindAncestor。 4)使用某种路由事件,并在控制级别处理它。它将通过附加的行为从数据模板中触发(google it!)。事件将传递数据,事件处理程序将在控件上设置相关属性。

    选项 1,3 与您的建议类似。选项 2、4 不同。在优雅方面,我更喜欢选项2。

    此外 - 请注意所有解决方案中的冲突。如果 DataTemplate 在单个控件内多次实例化,则所有实例都将尝试设置控件的属性。效果将是最后一次执行的集合尝试的效果,如果您无法控制它们的顺序,在某些情况下可能会出现问题。

    亚历克斯。

    【讨论】:

    • 我不认为选项 2 真的适合我的情况。这两件事并不真正了解彼此或共享任何东西。选项 4 对我来说听起来是最好的 - 但是你能在 XAML 中处理一个事件并设置一个属性吗?我不认为你可以。
    【解决方案2】:

    假设您的祖先在数据模板内部,您可以使用“名称”属性为该祖先命名。一旦有了名称,您就可以使用 setter 的“TargetName”来指定该祖先。

    例子:

    <DataTemplate>
        <Grid Name="ControlGrid">
            <Path x:Name="Arrow" Fill="Black">
                <Path.Triggers>
                    <Trigger Property="IsEnabled" Value="false">
                        <Setter Property="Visibility" TargetName="ControlGrid" Value="Collapsed"/>
                    </Trigger>
                </Path.Triggers>
            </Path>
        </Grid>
    </DataTemplate>
    

    【讨论】:

    • 不,我需要针对不同的控件 - 否则它是微不足道的。
    猜你喜欢
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多