Должен ли я использовать DataTemplates или UserControl, чтобы показать различные элементы управления для расширенных классов? - PullRequest
2 голосов
/ 14 декабря 2010

У меня есть класс User и класс Author, который расширяет User. У меня есть ObservableCollection отображается в ListBox. Для этого у меня есть DataTemplate для отображения каждого элемента, а другой - для отображения каждого выбранного элемента. У меня также есть столбец TextBoxes, которые связаны со свойствами свойства ListBox.SelectedItem. Пока все хорошо.

В данный момент я отображаю дополнительные элементы управления в столбце и шаблонах данных, если выбранный пользователь является автором, и все работает нормально, но я обманываю. Я добавил свойство IsAuthor bool в класс User, чтобы я мог связать его и определить, был ли Пользователь автором. Я знаю, что это неправильно, но я не мог найти другого способа сделать это, поэтому мой первый вопрос: как вы отображаете расширенные классы иначе, чем базовый класс? Я попробовал другой DataTemplate для типа Author, но он никогда не работал ... может быть, потому что коллекция была типа User?

Второй вопрос: нужно ли мне иметь все многие элементы управления TextBox в столбце в пользовательском элементе управления и изменить связанные элементы управления «Видимость автора», или каким-то образом поместить их в DataTemplate и создать один для каждого типа? В настоящее время я использую первый метод, и проблема заключается в том, что каждый элемент управления, связанный со свойством Author, генерирует ошибки (я вижу их в окне «Вывод» в Visual Studio), когда текущий выбранный элемент не является Author.

1 Ответ

3 голосов
/ 14 декабря 2010

У меня есть похожая настройка, которая использует шаблоны данных, и она прекрасно работает с унаследованными классами.Вот как я это сделал.

<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 у меня есть следующие шаблоны данных:

<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 списка.Два других шаблона данных используются элементом управления контентом при определении того, что отображать для выбранного элемента.Если выбранный элемент является просто пользователем, будет отображаться шаблон данных пользователя, если выбран автор, будет показан шаблон данных автора.

x: Тип локальный: Автор ссылается на тип класса.local должен быть объявлен в ваших объявлениях пространства имен.

xmlns:local="clr-namespace:TestApp"

Имейте в виду, что это мое пространство имен, вам придется указать то, которое вы используете.И, конечно же, шаблоны данных являются лишь базовыми примерами, вероятно, вы захотите сделать что-то более приспособленное для вашего приложения.

Однако может быть раздражающим, что вам нужно определить два отдельных шаблона данных, которые почти точно одинаковы дляваши два класса.Хотя ты, конечно, мог.Я делаю это в своем собственном приложении (не в этом примере), потому что то, что я хочу отобразить для каждого типа, сильно отличается.

Так что может быть полезно создать общий 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>

Итак, как вы можете видеть, оба DataTemplates для User и для Author начинаются с использования DataTemplate под названием «UserTemplate».Но в DataTemplate Author мы добавим специфические свойства Author.

Надеюсь, это поможет.

...