也许我甚至没有以正确的方式思考这个问题,所以我愿意接受建议,但我想在创建和编辑时使用完全相同的视图。我不想说创建/编辑实体,因为它比这更复杂。我有嵌套视图(使用Catel实现),因此每个嵌套视图也有自己的viewmodel。但是,执行的内部状态和命令会有所不同,具体取决于您是创建还是编辑(在父视图和嵌套视图中)。立即想到的两个想法是:
1)有一个策略模式的视图模型,其中执行的操作(创建相关或相关的编辑)与激活视图的消息一起传递。
2)不知何故有2个视图模型可以与同一个视图关联,也可以在它们之间切换。
建议?
答案 0 :(得分:3)
MVVM模式允许您为单个ViewModels
提供多个View
。通常它指的是View
,它可以有多个动作/状态。在ViewModels
之间切换可以“手动”或使用不同的模式,例如使用策略。
下面我将讨论这两个原则。
<强> Using the strategy pattern
强>
此模式允许您拥有一组实现特定策略算法的类。一个简单的例子:你需要从家里上班(学习地点等)。这可以通过以下几种方式完成:
所有这些都可以归结为单一策略,其中包括几种解决特定任务的方法。允许从“四人帮”一书中引用战略模式的适用性:
在以下情况下使用策略模式:
许多相关类只在行为上有所不同。策略提供了一种使用多种行为之一配置类的方法。
您需要不同的算法变体。例如,您可以定义反映不同空间/时间权衡的算法。当这些变体作为算法的类层次结构实现时,可以使用策略。
算法使用客户端不应该知道的数据。使用策略模式可以避免暴露复杂的,特定于算法的数据结构。
一个类定义了许多行为,这些行为在其操作中显示为多个条件语句。而不是很多条件,将相关的条件分支移动到他们自己的Strategy
类。
结构图:
Conclusion for Strategy pattern
如果您针对不同类型使用多个操作(C
reate R
emove U
pdate D
elete),例如:添加图片,添加用户信息,添加文件,也可以有子类型,然后我认为该策略适合你。
<强> Using several ViewModels for one View
强>
正如我上面提到的,MVVM模式允许一个ViewModels
多个View
。在我看来,最好使用DataTemplate
和选择器DataTemplateSelector
,它将根据条件返回所需的模板。 DataTemplate
适用于ViewModel
的视觉呈现。就个人而言,我使用动态DataTemplateSelector
,例如:
<ContentControl Name="DynamicContentRightPanel"
Style="{StaticResource ContentControlRightPanelStyle}"
Content="{Binding Path=ContentRightPanelModel.ContentType,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}" />
在面板中可能有不同的内容,这取决于用户的选择。
ContentControlRightPanelStyle
<Style x:Key="ContentControlRightPanelStyle" TargetType="{x:Type ContentControl}">
<Setter Property="ContentTemplateSelector" Value="{StaticResource MyTemplateSelector}" />
<Setter Property="DataTemplateSelectors:DynamicTemplateSelector.Templates">
<Setter.Value>
<DataTemplateSelectors:TemplateCollection>
<DataTemplateSelectors:Template Value="DateCalculator"
DataTemplate="{StaticResource DateCalcTemplate}" />
<DataTemplateSelectors:Template Value="Test"
DataTemplate="{StaticResource TestTemplate}" />
</DataTemplateSelectors:TemplateCollection>
</Setter.Value>
</Setter>
</Style>
DynamicTemplateSelector (taken and little reworked from CodeProject)
public class DynamicTemplateSelector : DataTemplateSelector
{
#region Templates Dependency Property
public static readonly DependencyProperty TemplatesProperty =
DependencyProperty.RegisterAttached("Templates", typeof(TemplateCollection), typeof(DataTemplateSelector),
new FrameworkPropertyMetadata(new TemplateCollection(), FrameworkPropertyMetadataOptions.Inherits));
public static TemplateCollection GetTemplates(UIElement element)
{
return (TemplateCollection)element.GetValue(TemplatesProperty);
}
public static void SetTemplates(UIElement element, TemplateCollection collection)
{
element.SetValue(TemplatesProperty, collection);
}
#endregion
#region SelectTemplate
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
string myStringItem = (string)item;
if (!(container is UIElement))
{
return base.SelectTemplate(item, container);
}
TemplateCollection templates = GetTemplates(container as UIElement);
if (templates == null || templates.Count == 0)
{
base.SelectTemplate(item, container);
}
foreach (var template in templates)
{
if (myStringItem.Equals(template.Value.ToString()))
{
return template.DataTemplate;
}
}
return base.SelectTemplate(item, container);
}
#endregion
}
#region TemplateCollection
public class TemplateCollection : List<Template>
{
}
#endregion
#region Template Dependency Object
public class Template : DependencyObject
{
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(Template));
public static readonly DependencyProperty DataTemplateProperty =
DependencyProperty.Register("DataTemplate", typeof(DataTemplate), typeof(Template));
public string Value
{ get { return (string)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } }
public DataTemplate DataTemplate
{ get { return (DataTemplate)GetValue(DataTemplateProperty); } set { SetValue(DataTemplateProperty, value); } }
}
#endregion
Conclusion for several ViewModels / one main View
如果用户的选择仅限于一种类型的操作(可能是几种),您可以简单地为每个ViewModel / View
创建(在DataTemplate的情况下),因为它将更容易和更方便。 / p>
答案 1 :(得分:0)
我会尝试重复使用尽可能多的逻辑,其中选项1为您提供了最多选项。你甚至可以想到这种情况:
public void PersonViewModel()
{
// Will be used when no model is available - create mode
public PersonViewModel()
: this(null) { }
// Will be used when a model is available - edit mode
public PersonViewModel(IPerson person)
{
// Here you check if you have a person object, if so, edit
}
}