简体   繁体   English

C#/ WPF:绑定到视觉/逻辑树外部的元素

[英]C#/WPF: Binding to an element outside of the visual/logical tree

I'm using the DropDownButton control from the Extended WPF Toolkit. 我正在使用扩展WPF工具包中的DropDownButton控件。 Inside of that, I'm hosting a ListBox which, upon change of selected element, should hide the containing DropDownButton. 在其中,我托管了一个ListBox,在更改所选元素时,该ListBox应该隐藏包含的DropDownButton。

My initial approach to do so in conjunction with Microsoft's interactivity framework was: 我最初与Microsoft的交互框架结合使用的方法是:

<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>

But this didn't work as WorkspaceSelectorContainer isn't found. 但这不起作用,因为找不到WorkspaceSelectorContainer。 Instead of binding by ElementName, I tried finding the ancestor of type DropDownButton, but this did not work either; 我尝试不查找ElementName的绑定,而是尝试查找DropDownButton类型的祖先,但这也不起作用。 tracing the binding showed it only resolved ancestors up to the outer most element of DropDownButton.DropDownContent, but not any further; 跟踪绑定表明,它仅解析祖先,直到DropDownButton.DropDownContent的最外层元素为止,而没有任何其他元素; eg the DropDownButton itself wasn't part of the ancestor tree. 例如DropDownButton本身不属于祖先树。

Ok, so my next approach was 好的,所以我的下一个方法是

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

but that did not work either as it threw an Exception 但这并没有起作用,因为它引发了异常

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. 

Don't know what else to try anymore. 不知道还能尝试什么。 Does anyone have an idea how to solve this? 有谁知道如何解决这个问题?

Would it be possible to somehow reference my root grid that contains everything, and search for the DropDownButton element from there? 是否可以以某种方式引用我包含所有内容的根网格,然后从那里搜索DropDownButton元素? Something like {Binding Source={x:Reference MyRootGrid}, ElementName=WorkspaceSelectorContainer} (this doesn't work as I can't combine source and ElementName) 诸如{Binding Source = {x:Reference MyRootGrid},ElementName = WorkspaceSelectorContainer}之类的东西(此方法不起作用,因为我无法合并source和ElementName)

Thanks! 谢谢!

Well I had the same problem (albeit in Silverlight). 好吧,我有同样的问题(尽管在Silverlight中)。 Solved it by introducing a resource object that has a reference to the DropDownButton and that can easily be bound from within the DropDownContent: 通过引入资源对象解决了此问题,该资源对象具有对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>

...and the magic object ...和魔术对象

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" />

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM