2

RegisterUserViewModel と UserViewModel の 2 つのビュー モデルを持つ MVVM アプリケーションを作成しています。「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」クラスには、Active Directory から取得したユーザーの名前が取り込まれる「UsersFromAD」プロパティもあります。

私の問題は、ビュー内からのデータ バインディングにあります。

ウィンドウを 2 つの領域 (左右) に分割する MainWindow ビューがあります。左側の領域には使用可能なコマンドのリストがあり、右側の領域にはタブ コントロールがあります。左側のコマンドは、タブ コントロールで新しいタブを開くために使用されます。TabControl の ItemsSource プロパティは、「ViewModelBase」クラスのコレクションにバインドされています。TabControl で開かれている各タブは、開かれているクラスのタイプに応じて、DataTemplate バインディングにより特定のビューに自動的にバインドされます。

もっと明確にしましょう:

1) 左側に、TabControl の ItemsSource プロパティがバインドされている "ObservableCollection" に "RegisterUserViewModel" の新しいインスタンスを追加するコマンドがあります。

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 に表示されます。

ただし、データグリッドの「Name」列で 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')

これらのバインディングを正しく設定するのを手伝ってくれる人はいますか?

4

2 に答える 2

1

FindAncestor は、ツリー内の要素の DataContext ではなく、要素ツリー内の型を検索しています。したがって、列の ItemSource をバインドするには、次のことを試すことができます(オブジェクトグラフを理解しているため)

<DataGridComboBoxColumn ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type View:RegisterUserView}}, Path=DataContext.UsersFromAD}"
                        />
于 2013-04-11T00:27:32.197 に答える