2013-04-10 86 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