2

User クラスと、User を拡張する Author クラスがあります。ObservableCollection<User> が ListBox に表示されています。このために、各項目を表示するための DataTemplate と、選択した各項目を表示するための別の DataTemplate があります。また、ListBox.SelectedItem プロパティのプロパティにバインドされた TextBoxes の列もあります。ここまでは順調ですね。

現時点では、選択したユーザーが作成者であり、すべて正常に動作する場合、列と DataTemplates に追加のコントロールを表示していますが、不正行為をしています。IsAuthor bool プロパティを User クラスに追加して、それにバインドし、User が Author であるかどうかを判断できるようにしました。私はそれが間違っていることを知っていますが、それを行う他の方法を見つけることができませんでした. タイプ Author に対して別の DataTemplate を試しましたが、うまくいきませんでした... コレクションのタイプが User だったからでしょうか?

2 番目の質問は、UserControl の列に多数の TextBox コントロールをすべて配置し、Author 関連のコントロールの Visibility を変更するか、何らかの方法でそれらを DataTemplate に入れて、タイプごとに 1 つ作成する必要があるかということです。現在、最初の方法を使用していますが、問題は、現在選択されているアイテムが作成者ではない場合、作成者プロパティにバインドされた各コントロールがエラーをスローすることです (Visual Studio の [出力] ウィンドウで確認できます)。

4

1 に答える 1

3

データ テンプレートを使用する同様のセットアップがあり、継承されたクラスで問題なく動作します。これが私がやった方法です。

<ListBox Name="UserList" ItemsSource="{Binding Path=Users}"
         ItemTemplate="{StaticResource ShowUserName}"
         SelectedItem="{Binding Path=SelectedUser, Mode=TwoWay}">
</ListBox>
<ContentControl Content="{Binding ElementName=UserList, Path=SelectedItem}"/>

Window.Resources セクションには、次の DataTemplates があります。

<DataTemplate x:Key="ShowTime" DataType="TestApp.User">
    <TextBlock Text="{Binding Path=Name}" HorizontalAlignment="Center"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:User}">
   <StackPanel Margin="10">
     <TextBlock Text="{Binding Path=Name}"/>
     <TextBlock Text="{Binding Path=Age}"/>
   </StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Author}">
   <StackPanel Margin="10">
     <TextBlock Text="{Binding Path=Name}"/>
     <TextBlock Text="{Binding Path=Age}"/>
     <TextBlock Text="{Binding Path=FirstTitle}"/>
   </StackPanel>
</DataTemplate>

最初のテンプレートは、リスト自体に表示されるものです。リストボックスの ItemTemplate プロパティのキーで参照しています。他の 2 つのデータ テンプレートは、選択したアイテムの表示対象を決定するときに、コンテンツ コントロールによって使用されます。選択した項目がユーザーのみの場合はユーザーの DataTemplate が表示され、作成者が選択されている場合は作成者の DataTemplate が表示されます。

x:Type local:Author は、クラス タイプを参照しています。local は名前空間宣言で宣言する必要があります。

xmlns:local="clr-namespace:TestApp"

これは私の名前空間であることに注意してください。使用しているものを指定する必要があります。もちろん、データ テンプレートは基本的な例にすぎません。おそらく、アプリケーションに合わせてさらに調整したいでしょう。

ただし、2 つのクラスに対してほぼ同じである 2 つの別個の Data テンプレートを定義しなければならないのは面倒かもしれません。確かにできますが。タイプごとに表示したいものが大きく異なるため、私は自分のアプリケーションでそれを行います (この例ではありません)。

したがって、すべてのユーザー プロパティに共通の DataTemplate を作成し、この DataTemplate を作成者用に単純に拡張すると便利です。これを行いたい場合は、次のようにテンプレートを設定できます。

<DataTemplate x:Key="UserTemplate">
  <!-- show all the properties of the user class here -->
</DataTemplate>
<DataTemplate DataType="{x:Type local:User}">
  <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource UserTemplate}"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:Author}">
  <StackPanel>
    <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource UserTemplate}"/>
    <!-- show all the additional Author properties here -->
  </StackPanel>
</DataTemplate>

ご覧のとおり、User と Author の両方の DataTemplate は、"UserTemplate" という DataTemplate を使用して開始されます。ただし、Author DataTemplate では、Author 固有のプロパティを追加します。

それが役立つことを願っています。

于 2010-12-14T01:26:28.707 に答える