首页 文章

WPF Hierarchical ViewModel FindAncestor数据绑定错误

提问于
浏览
2

我正在创建一个MVVM应用程序,它有两个视图模型,RegisterUserViewModel和UserViewModel . “RegisterUserViewModel”有一个公共属性,它是“UserViewModel”的集合,如下面的代码所示

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集合(Users) . 一切正常,添加到集合中的用户显示在DataGrid上 .

但是,我想要的是数据网格上的“名称”列使用DataGridComboBoxColumn,其ItemsSource属性设置为“UsersFromAD”属性,该属性位于我的“RegisterUserViewModel”类中 .

为此,我使用了以下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 回答

  • 1

    我通过将RegisterViewSource添加到我的RegisterUserView的“UserControl.Resources”部分并将CollectionViewSource绑定到我的UsersFromAD属性来解决了这个问题,如下所示:

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

    然后,通过将我的DataGridComboBoxColumn绑定到我的CollectionViewSource,如下所示:

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

    FindAncestor正在搜索 element tree 中的类型而不是树中元素的DataContext中的类型 . 因此,对于绑定ItemSource的列,您可以尝试下载(因为我理解您的对象图)

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

相关问题