Я создал следующую модель (код упрощен для иллюстрации ситуации):
public abstract class Account
{
public string Name { get; set; }
}
public class Person : Account
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Company : Account
{
public string Owner { get; set; }
}
Далее я создал модель вида:
public class ViewModel
{
public Account Model { ... }
public string Name { ... }
public string FirstName { ... }
public string LastName { ... }
public string Owner { ... }
...
}
И, наконец, мнение:
<UserControl>
<UserControl.Resources>
<!-- Person data template -->
<DataTemplate x:Key="personTemplate" DataType="{x:Type model:Person}">
<Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
</Grid>
</DataTemplate>
<!-- Company data template -->
<DataTemplate x:Key="companyTemplate" DataType="{x:Type model:Company}">
<Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=Owner}" />
</Grid>
</DataTemplate>
<!-- Data template selector for different account types -->
<local:AccountTemplateSelector x:Key="templateSelector"
PersonTemplate="{StaticResource personTemplate}"
CompanyTemplate="{StaticResource companyTemplate}" />
</UserControl.Resources>
<StackPanel Name="rootLayout" DataContext="{Binding Path=viewModel}">
<ContentControl Content="{Binding Path=Model}"
ContentTemplateSelector="{StaticResource templateSelector}"/>
<Button Content="Save" />
<Button Content="Close" />
</StackPanel>
</UserControl>
Итак, когда загруженная модель имеет тип Person
, отображается personTemplate
; наоборот, когда модель Company
, отображается companyTemplate
.
Мои вопросы:
- Имеет ли этот подход смысл? Разумнее было бы удалить
Model
свойство в классе ViewModel
и ввести перечисление или просто bool
который покажет человеку, если true
, или компании, если `ложь?
- При определении шаблонов данных я указывал
DataType
с Person
и Company
типы (это было естественно для меня). Нужно ли это вообще, потому что в самом
Следующая строка Я устанавливаю новый контекст данных, который будет из UserControl
?
- Если
DataType
s шаблонов данных будут разными моделями представления, что-то вроде
PersonViewModel
и CompanyViewModel
? Имеет ли смысл их создавать?
- Как я могу, и могу ли я вообще заставить шаблон данных наследовать контекст данных из
ContentControl
автоматически?
Я знаю, что в конечном итоге все это зависит от личного выбора, но так как я изучаю MVVM (я использую MVVM Light), мне интересно, какой подход будет наиболее рекомендуемым? Я до сих пор не до конца понимаю, когда следует использовать классы из моделей в качестве типов данных для шаблонов данных и когда следует использовать модели просмотра для этой цели. Следует ли ссылаться на сборку, которая представляет модель, даже в сборке вида (при условии, что вид, модель и модель вида находятся в отдельных сборках)?
Спасибо за все разъяснения!
ОБНОВЛЕНИЕ:
Это обновление должно объяснить проблему наличия классов модели как DataType
s в шаблонах данных, когда свойство класса модели напрямую не привязано только к одному элементу управления в представлении.
В Person
есть перечисление и новое свойство, поэтому теперь оно выглядит так:
public class Person : Account
{
public enum GenderType { Female, Male, NotSpecified }
public string FirstName { get; set; }
public string LastName { get; set; }
public GenderType Gender {get; set; }
}
И в представлении, шаблон данных человека также изменяется, конечно:
<!-- Person data template -->
<DataTemplate x:Key="personTemplate" DataType="{x:Type model:Person}">
<Grid DataContext="{Binding ElementName=rootLayout, Path=DataContext}">
<TextBlock Text="{Binding Path=Name}" />
<TextBlock Text="{Binding Path=FirstName}" />
<TextBlock Text="{Binding Path=LastName}" />
<RadioButton Name="Female" />
<RadioButton Name="Male" />
<RadioButton Name="NotSpecified" />
</Grid>
</DataTemplate>
Если Content
для ContentControl
установлено в Model
свойство ViewModel
, как бы я разрешил ситуацию с полами / переключателями; потому что теперь они не совпадают по способу один элемент управления / одно свойство?