2013-04-10 66 views
2

我創建了一個MVVM應用程序,它有兩個視圖模型,RegisterUserViewModel和UserViewModel。該「RegisterUserViewModel」具有公共屬性,它是「UserViewModel」的集合,如下面所示WPF Hierarchical ViewModel FindAncestor數據綁定錯誤

public class RegisterUserViewModel : ViewModelBase 
{ 
    public ObservableCollection<UserViewModel> Users { get; } 
    public ObservableCollection<string> UsersFromAD { get; } 
} 

public class UserViewModel : ViewModelBase 
{ 
    public string Name { get; set; } 
} 

代碼中的「RegisterUserViewModel」類還具有填充了所獲得的用戶名的「UsersFromAD」屬性來自Active Directory。

我的問題在於我的視圖中的數據綁定。

我有一個MainWindow視圖,它將窗口分成兩個區域(左側和右側):左側區域包含可用命令列表,右側區域包含選項卡控件。 左側的命令用於打開選項卡控件上的新選項卡。 TabControl的ItemsSource屬性綁定到一組「ViewModelBase」類。由於DataTemplate綁定,TabControl中的每個打開的選項卡都會自動綁定到特定視圖,具體取決於正在打開的類的類型。

讓我更清楚:

1)我有,增加了「RegisterUserViewModel」的新實例對其中的TabControl的ItemsSource屬性綁定的「的ObservableCollection」左邊的一個命令。

2)MainWindow.xaml文件有一個部分,它指定了結合RegisterUserViewModel特定視圖一個DataTemplate,如示於以下的代碼:

<Window.Resources> 
    <ResourceDictionary> 
     <DataTemplate DataType={x:Type ViewModel:RegisterUserViewModel}"> 
      <View:RegisterUserView /> 
     </DataTemplate> 
    <ResourceDictionary> 
<Window.Resources> 

3)通過這樣做,WPF自動設置我的RegisterUserView的DataContext到我的RegisterUserViewModel。

現在,我已經將DataGrid控件添加到了我的RegisterUserView,並將其ItemsSource設置爲我的UserViewModel集合(用戶)。一切正常,添加到集合中的用戶顯示在DataGrid上。

但是,我想要的是數據網格上的「名稱」列使用DataGridComboBoxColumn,其ItemsSource屬性設置爲位於我的「RegisterUserViewModel」類上的「UsersFromAD」屬性。

對於這一點,我用下面的XAML代碼:

<DataGridComboBoxColumn ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ViewModel:RegisterUserViewModel}}, Path=UsersFromAD}" 
         SelectedValueBinding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ViewModel:UserViewModel}}, Path=Name}" 
         /> 

然而,這是行不通的。每當我運行應用程序,我從輸出窗口得到以下內容:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='TestApplication.ViewModel.RegisterUserViewModel', AncestorLevel='1''. BindingExpression:Path=UsersFromAD; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=24004376); target property is 'ItemsSource' (type 'IEnumerable') 
System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='TestApplication.ViewModel.UserViewModel', AncestorLevel='1''. BindingExpression:Path=Name; DataItem=null; target element is 'TextBlockComboBox' (Name=''); target property is 'SelectedValue' (type 'Object') 

任何人都可以幫助我正確設置這些綁定?

回答

2

我加入了CollectionViewSource我的「用戶控件解決了這個問題。資源」我RegisterUserView的部分和CollectionViewSource綁定到我的UsersFromAD屬性,象下面這樣:

<UserControl.Resources> 
    <CollectionViewSource x:Key="cvsUsersFromAD" Source="{Binding UsersFromAD}" /> 
</UserControl.Resources> 

,然後通過我的DataGridComboBoxColumn結合我CollectionViewSource,如下圖所示:

<DataGridComboBoxColumn ItemsSource="{Binding Source={StaticResource cvsUsersFromAD}}" 
         /> 
1

FindAncestor正在尋找類型爲元素樹不在DataContext中的元素在樹中。因此,對於綁定列的ItemSource你可以嘗試如下因素(據我瞭解你的對象圖)

<DataGridComboBoxColumn ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type View:RegisterUserView}}, Path=DataContext.UsersFromAD}" 
         /> 
+0

當我這樣做,我收到一個編譯錯誤:「錯誤:類型引用無法找到名爲'RegisterUserView'的公共類型。 – Samir 2013-04-11 21:21:59

+0

@Samir你有RegisterUserView類嗎?你是否將xmlns:View綁定到它所在的名稱空間? – shibormot 2013-04-11 21:56:21

+0

我通過修復名稱空間聲明來解決編譯器錯誤。但是,我仍然收到錯誤:System.Windows.Data錯誤:無法找到與參考'RelativeSource FindAncestor,AncestorType ='TestApplication.View.RegisterUserView',AncestorLevel ='1'綁定的源代碼。 BindingExpression:路徑= DataContext.UsersFromAD;的DataItem = NULL;目標元素是'DataGridComboBoxColumn'(HashCode = 24004376);目標屬性是'ItemsSource'(鍵入'IEnumerable') – Samir 2013-04-12 12:17:31