2010-01-15 93 views
6

如何在其ResourceDictionary內綁定到UserControl的屬性?我希望對象我在資源聲明具有相同DataContext作爲UserControl它包含在:從ResourceDictionary中綁定到祖先

<UserControl 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Some.Namespace" 
    DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Self}}"> 
    <UserControl.Resources> 
     <local:SomeClass 
      x:Key="SomeClass" 
      DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" /> 
    </UserControl.Resources> 
</UserControl> 

在運行時出現錯誤:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='UserControl', AncestorLevel='1''. BindingExpression:Path=DataContext; DataItem=null; target element is 'SomeClass' (Name=''); target property is 'DataContext' (type 'Object')

+0

設置在DataContext直接在代碼隱藏的工作原理,但我想要XAML溶液... ((SomeClass的)this.Resources [ 「SomeClass的」])的DataContext =視圖模型。 –

+0

我認爲繼承上下文可能會影響這個問題... http://blogs.msdn.com/nickkramer/archive/2006/08/18/705116.aspx –

回答

2

我的解決方法是設置資源的DataContext在代碼隱藏。

的.xaml

<local:SomeType x:Key="SomeKey" SomeProperty="{Binding ... }" /> 

.xaml.cs

public SomeControl() 
{ 
    InitializeComponent(); 
    ((SomeType)this.Resources["SomeKey"]).DataContext = this; 
} 
+0

感謝您回答您自己的問題(認真)。我從來沒有見過這個問題的XAML解決方案。它也影響ContextMenu,MenuItem和MenuItem.Icon。讓我發狂。這似乎破壞了XAML的目的。 – kevinarpe

0

我想你」重新尋找只是綁定到繼承的DataContext的{綁定}。下面是一個例子,雖然有點怪顯示瞭如何抓住一個顏色通過綁定到DataContext:

<Window x:Class="AncestorBinding.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources> 
     <SolidColorBrush x:Key="MyBrush" Color="Blue" /> 
    </Window.Resources> 
    <StackPanel> 
     <Button DataContext="{Binding Source={StaticResource MyBrush}}" Content="My Button"> 
      <Button.Resources> 
       <Style TargetType="{x:Type Button}"> 
        <Setter Property="Background" Value="{Binding}" /> 
       </Style> 
      </Button.Resources> 
     </Button> 
    </StackPanel> 
</Window> 
+0

不幸的是{綁定}不適合我 - 找不到提供DataContext的元素。 BindingExpression :(無路徑);的DataItem = NULL;目標元素是'SomeClass'(Name ='');目標屬性是'DataContext'(類型'對象') –

+0

您是否嘗試過沒有設置DataContext?我會認爲你的本地:SomeClass會從UserControl繼承DataContext。 –

+0

我最初遇到這個問題,因爲我根本沒有設置DataContext:http://stackoverflow.com/questions/2073170 –

0

我會怎麼做,是創建用戶控制附加的行爲(ContextualizeResourceBehavior),並指定資源關鍵在於附加的行爲。該行爲將查找資源(不確定您是否可以在連接時執行此操作,如果不是,則需要連接Loaded事件)並傳輸數據上下文。

0

當您將資源添加到可視化樹時,它應該繼承數據上下文。但...看看element spy它可能只是做你所需要的。

1

使用FindAncestor時,目標元素必須是源的後代(邏輯或視覺)。你的對象不會出現在視覺或邏輯樹中,它只是在資源中。所以你不能使用FindAncestor的RelativeSource作爲你的對象。

雖然您可以在Binding中使用ElementName。像這樣的東西應該工作:

<UserControl x:Name="userControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Some.Namespace" 
    DataContext="{Binding Path=ViewModel, RelativeSource={RelativeSource Self}}"> 
    <UserControl.Resources> 
     <local:SomeClass 
      x:Key="SomeClass" 
      DataContext="{Binding Path=DataContext, ElementName=userControl}" /> 
    </UserControl.Resources> 
</UserControl> 
+3

這不適合我。綁定找不到使用x:Name或Name的元素名稱。 –

0

設置x:Shared = 「假」,這將克隆在每次使用資源,並使其成爲一個孩子你的元素,使綁定的使用。

<local:SomeClass 
      x:Key="SomeClass" 
      x:Shared="False" 
      DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />