Я новичок в WPF и MVVM. Я пытаюсь связать два разных DataTemplates с двумя разными типами объектов в одном ContentControl. Каждый вид объекта соответствует одному DataTemplate.
Два вида объектов называются Единица и Компонент соответственно. Они содержат разные свойства. Например, юнит имеет 3 свойства: Id , Имя и Производство . Компонент имеет 3 свойства Id , Тип и Материалы . Пример кода следующий:
public class Unit : INotifyPropertyChanged
{
private int _id;
private string _name;
private string _manufacture;
public int Id
{
get {return this._id}
set
{
this._id = value;
OnPropertyChanged("Id")
}
{
public string Name
{
get {return this._name}
set
{
this._id = value;
OnPropertyChanged("Name")
}
{
public string Manufacture
{
get {return this._manufacture}
set
{
this._id = value;
OnPropertyChanged("Manufacture")
}
{
public event PropertyChangedEventHandler PropertyChanged;
...
}
Класс Component имеет аналогичную структуру.
В MainWindow у меня есть ListBox, перечисляющий имена объектов (я буду менять его на TreeView в будущем) слева, и ContentControl справа. Я хочу, чтобы при выборе имени объекта детали объекта отображались справа. Код MainWindow выглядит следующим образом:
<Windows.Resources>
<CollectionViewSource
Source="{Binding Source={x:Static Application.Current}, Path=UnitItems}"
x:Key="UnitDataView">
</CollectionViewSource>
<CollectionViewSource
Source="{Binding Source={x:Static Application.Current}, Path=ComponentItems}"
x:Key="ComponentDataView">
</CollectionViewSource>
<CompositeCollection x:Key="AllDataView
<CollectionContainer Collection="{Binding Source={StaticResource UnitDataView}}" />
<CollectionContainer Collection="{Binding Source={StaticResource ComponentDataView}}" />
</CompositeCollection>
<local: PartDataTemplateSelector x:Key="MyDataTemplateSelector"
UnitTemplate="{StaticResource unitTemplate}"
ComponentTemplate="{StaticResource componentTemplate}" />
</Windows.Resources>
<Grid>
<Grid.ColumnDefinition>
<ColumnDefinition>
<ColumnDefinition>
</Grid.ColumnDefinition>
<ListBox x:Name="ComponentListView" Grid.Column="0"
ItemsSource="{Binding Source={StaticResource AllDataView}}" />
<TabControl Grid.Column="1"
<TabItem Header="Basic Info">
<ContentControl x:Name="BasicInfoContent"
ContentTemplateSelector="{StaticResource MyDataTemplateSelector}"
Content="{Binding Source={StaticResource AllDataView}}">
</ContentControl>
</TabItem>
</TabControl>
</Grid>
UnitItems
и ComponentItems
- это два ObservableCollection<T>
объекта, определенных в App.xaml.cs. И я определил некоторые DataTemplates в App.xaml. Пример кода приведен ниже:
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="..."
</ResourceDictionary.MergedDictionaries>
<DataTemplate DataType="{x:Type src:Unit}">
<!-- This template is to show the name of a unit object in the ListBox -->
</DataTemplate>
<DataTemplate DataType="{x:Type src:Component}">
<!-- This template is to show the name of a component object in the ListBox -->
</DataTemplate>
<DataTemplate x:Key="unitTemplate" DataType="{x:Type src:Unit}">
<!-- This template is to show the details of a unit object in the ContentControl -->
</DataTemplate>
<DataTemplate x:Key="componentTemplate" DataType="{x:Type src:Component}">
<!-- This template is to show the details of a component object in the ContentControl -->
</DataTemplate>
</Application.Resources>
А мой пользовательский DataTemplateSelector выглядит так:
class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate UnitTemplate { get; set; }
public DataTemplate ComponentTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
swith (item)
{
case Unit _:
return UnitTemplate;
case Component _:
return ComponentTemplate;
}
return null;
}
}
Я прочитал эту статью ContentTemplateSelector и попробовал ContentTemplateSelector, но, поскольку я использую CompositeCollection и CollectionContainer для связывания этих двух видов объектов в ContentControl, объект item в моем классе DataTemplateSelector получает тип CompositeCollection , а не тип модуля или тип компонента, поэтому верный шаблон не возвращается. Также я попробовал метод, упомянутый в этой статье Свойство DataType , который должен установить свойство DataType для каждого из DataTemplate и установить путь к «/». Может быть, я неправильно понял, но это тоже не сработало, где я думаю, что у него такая же проблема, как и у ContentTemplateSelector. Кто-нибудь может мне помочь в этой проблеме?
Я впервые задаю вопрос о переполнении стека. Я знаю, что некоторые из моих описаний и кодов тривиальны для этого вопроса, но я просто не хочу пропустить какие-либо детали, которые могут быть связаны с моей проблемой. Я прошу прощения за это. Также, если есть какие-либо проблемы с моим стилем кодирования и структурой данных, пожалуйста, не стесняйтесь указывать на это. Я очень ценю это. Спасибо за ваше чтение и помощь!