2015-08-03 51 views
2

我使用擴展WPF工具包中的DropDownButton控件。在裏面,我主持一個ListBox,當改變選定的元素時,應該隱藏包含DropDownButton。C#/ WPF:綁定到視覺/邏輯樹之外的元素

我在與微軟的互動框架一起這樣做最初的做法是:

<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元素? {Binding Source = {x:Reference MyRootGrid},ElementName = WorkspaceSelectorContainer}(這不起作用,因爲我無法組合源和ElementName)

謝謝!

+0

您的標記有zombi標記。 – Martin

回答

3

那麼我有同樣的問題(儘管在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)); 
} 
+0

這樣一個優雅的方式,終於謝謝這麼多先生! – AgentFire

0
<ie:ChangePropertyAction PropertyName="IsOpen" Value="False" 
         TargetName="WorkspaceSelectorContainer" /> 
+0

不幸的是,這也行不通。雖然我不知道如何可能調試這一個,但我想這個問題可能與嘗試使用ElementName = ...綁定TargetObject時相同...... – Bogey

+0

hmm,嘗試將ListBox添加到與DropDownButton相同的NameScope - 例如在ListBox.Initialized事件中。只是從內存:'NameScope.SetNameScope(MyListBox,NameScope.GetNameScope(WorkspaceSelectorContainer);' – Liero