[一种编写具有属性的类的方法,该属性将返回ViewModel的新实例

问题描述 投票:0回答:2

[我们有一个WPF应用程序,其登录页面列出了大约十二个按钮,所有按钮都将转到该类型的新视图/视图模型。它变得笨拙。我们有一个viewmodel列出了所有基本上如下所示的所有视图:

    private void ExecuteViewProgramCommand()
    {
        OpenViewMessage message = new OpenViewMessage();
        CurrentViewModel = message.ViewModel = ViewModelLocator.ProgramVM;
        Messenger.Default.Send<OpenViewMessage>(message);
    }

我从不喜欢这样做的方式,因为它违反了DRY原则。在第二行的上述代码中唯一发生变化的地方是,在此代码中发生什么变化的是ViewModelLocator.ProgramVM。我的任务是重做登录页面,使登录页面更有条理,我们将添加更多启动按钮。我认为使用依赖注入会更好。另外,我正在尝试解决重新设计显示器的需求,以便将其显示在列表中,而不是按字母顺序排列在周围的按钮上。

首先,我想到了这堂课:

public class Tile
{
    public string ModuleName { get; set; }
    public NamedViewModelBase ModuleViewModel { get; set; }
}

((NamedViewModelBase是所有视图模型都通用的视图模型的名称。)然后我声明了一个单元测试来对其进行测试,并在单元测试中声明了它:

List<Tile> tiles = new List<Tile>()
{
    new Tile()
    {
        ModuleName = "Program",
        ModuleViewModel = ViewModelLocator.ProgramVM
    },
    new Tile()
    {
        ModuleName = "Organization",
        ModuleViewModel = ViewModelLocator.OrganizationVM
    }
}

但是很快就发现这是错误的。 ViewModelLocator.ProgramVM的设置器中的分配将实例化Program的视图模型。我不希望那样,我希望有实例化它的调用,例如我们在ViewModelLocator中使用的方法:

static public ProgramViewModel ProgramVM
{
    get
    {
        if (ServiceLocator.IsLocationProviderSet)
        {
            SimpleIoc ioc = ServiceLocator.Current as SimpleIoc;
            return ioc.GetInstanceWithoutCaching<ProgramViewModel>(Guid.NewGuid().ToString());
        }
        else
        {
            return null;
        }
    }
}

因此,我想我必须更改Tile类以将ModuleViewModel属性声明为类似以下内容:public NamedViewModelBase ModuleViewModel { get; }。但是我不知道在定义列表时如何实例化它。解决此问题的正确方法是什么?

c# wpf mvvm-light
2个回答
0
投票

这将是伪装的鳕鱼建议,有点像您已经在同一条轨道上:

假设BaseViewModel是所有单个VM的基类

  1. 创建字典
  2. 在应用程序启动期间填写此词典(看起来像您的图块列表)

    public void PreCreateVMs(){dictionary [Key] = new ConcreteViewModelType();//在这里继续添加新的Vms}

  3. 在xaml中,将所有按钮绑定到同一命令,该命令采用字符串参数(或使用Enum即兴实现)。为每个按钮传递正确的字符串键。像:单击“帐户”按钮应启动AccountVM,该帐户与“ AccountVM”键一起存储在字典中。

  4. 在命令处理程序中-使用字符串,查找字典,找到正确的ViewModel并将该对象分配给CurrentViewModel

从维护的角度来看,添加新的ViewModel所要做的就是用新的按钮更新xaml,分配正确的命令参数字符串。使用此字符串键,然后在PreCreateVMs方法中添加正确的VM。


0
投票

我已经重新设计了Tile类。我相信我需要的是第二个参数是Command。我问这是否可能会更好。这是Tile的新定义,以及我如何实现它的示例:

public class Tile
{
    public string ModuleName { get; set; }
    //public NamedViewModelBase ModuleViewModel { get; set; }
    public Action ThisCommand { get; set; }
}

这是我尝试将其实现为列表的方式:

List<Tile> tiles = new List<Tile>()
{
    new Tile()
    {
        ModuleName = "Program",
        ThisCommand = () => 
        {
            if (ServiceLocator.IsLocationProviderSet)
            {
                SimpleIoc ioc = ServiceLocator.Current as SimpleIoc;
                ioc.GetInstanceWithoutCaching<ProgramViewModel>(Guid.NewGuid().ToString());
            }
        }
    },
    new Tile()
    {
        ModuleName = "Organization",
        ThisCommand = () =>
        {
            if (ServiceLocator.IsLocationProviderSet)
            {
                SimpleIoc ioc = ServiceLocator.Current as SimpleIoc;
                ioc.GetInstanceWithoutCaching<OrganizationViewModel>(Guid.NewGuid().ToString());
            }
        }
    }
};

我在正确的轨道上吗?我应该将tiles定义为词典吗?

© www.soinside.com 2019 - 2024. All rights reserved.