c# /WPF:绑定到可视化/逻辑树之外的元素

本文关键字:元素 可视化 WPF 绑定 | 更新日期: 2023-09-27 18:06:16

我正在使用扩展WPF工具包中的DropDownButton控件。在这里面,我托管了一个ListBox,在改变所选元素时,应该隐藏包含DropDownButton。

结合微软的交互性框架,我最初的方法是:

<xctk:DropDownButton x:Name="WorkspaceSelectorContainer" Content="This is the active workspace">
                    <xctk:DropDownButton.DropDownContent>
                            <ListBox ItemsSource="{Binding workspaces}">
                                <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="SelectionChanged">
                                        <ie:ChangePropertyAction PropertyName="IsOpen" Value="False" TargetObject="{Binding ElementName=WorkspaceSelectorContainer}"/>
                                    </i:EventTrigger>
                                </i:Interaction.Triggers>
                            </ListBox>
                        </StackPanel>
                    </xctk:DropDownButton.DropDownContent>
                </xctk:DropDownButton>

但是这没有工作,因为没有找到WorkspaceSelectorContainer。而不是通过ElementName绑定,我试图找到类型DropDownButton的祖先,但这也没有工作;跟踪绑定显示它只解析了到DropDownButton最外层元素的祖先。DropDownContent,但没有进一步;例如,DropDownButton本身不是祖先树的一部分。

好的,我的下一个方法是

<ie:ChangePropertyAction PropertyName="IsOpen" Value="False" TargetObject="{Binding Source={x:Reference WorkspaceSelectorContainer}}"/>

,但这也没有工作,因为它抛出了一个异常

A first chance exception of type 'System.Xaml.XamlObjectWriterException' occurred in System.Xaml.dll
Additional information: Cannot call MarkupExtension.ProvideValue because of a cyclical dependency. Properties inside a MarkupExtension cannot reference objects that reference the result of the MarkupExtension. 

我不知道还能尝试什么了。有人知道怎么解决这个问题吗?

是否有可能以某种方式引用包含所有内容的根网格,并从那里搜索DropDownButton元素?像{绑定源={x:引用MyRootGrid}, ElementName=WorkspaceSelectorContainer}(这不起作用,因为我不能结合源和ElementName)

谢谢!

c# /WPF:绑定到可视化/逻辑树之外的元素

我也有同样的问题(尽管是在Silverlight中)。通过引入一个资源对象来解决这个问题,该对象有一个对DropDownButton的引用,并且可以很容易地从DropDownContent:

中绑定
<Foo.Resources>
    <BindableObjectReference
      x:Key="WorkspaceSelectorContainerReference"
      Object="{Binding ElementName=WorkspaceSelectorContainer}"/>
</Foo.Resources>
<DropDownButton x:Name="WorkspaceSelectorContainer" ...>
    <DropDownButton.DropDownContent>
        ...
        <ChangePropertyAction
            PropertyName="IsOpen"
            Value="False"
            TargetObject="{Binding Path=Object,
                Source={StaticResource WorkspaceSelectorContainerReference}}"/>
        ...
    </DropDownButton.DropDownContent>
</DropDownButton>

…和魔法对象

public class BindableObjectReference : DependencyObject
{
    public object Object
    {
        get { return GetValue( ObjectProperty ); }
        set { SetValue( ObjectProperty, value ); }
    }
    public static readonly DependencyProperty ObjectProperty =
        DependencyProperty.Register( "Object", typeof( object ),
        typeof( BindableObjectReference ), new PropertyMetadata( null ) );
}
<ie:ChangePropertyAction PropertyName="IsOpen" Value="False"
                         TargetName="WorkspaceSelectorContainer" />