如何从代码后台访问ViewModelLocator中的MainViewModel?

4
使用MVVM Light构建WP7应用程序,用于我的视图模型。当通过NuGet添加库时,我使用ViewModelLocator。非常好用,但现在我需要从代码中访问ViewModel。
在我的代码中,用户点击按钮,我需要搜索MainViewModel(其中包含多个视图模型),并根据用户输入的条件找到一个。
通常,我只需响应按钮的Click事件,但我没有ViewModelLocator类的实例变量来获取MainViewModel以执行搜索。对于Windows Phone 7的默认模板(非MVVMLight),App类具有指向主视图模型的静态变量,因此您可以随时使用App.ViewModel访问它。
有一些关于使用命令的Twitter讨论,这是很好的,但是最终我必须跨多个VM执行代码搜索,以获得所需的结果。可能需要将ISearchViewModel服务注入View或其他内容,以使其正常工作。
以下是提供的ViewModelLocator的实现:
public class ViewModelLocator
{
    private static MainViewModel _main;

    public ViewModelLocator()
    {
        _main = new MainViewModel();
    }

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
    "CA1822:MarkMembersAsStatic",
    Justification = "This non-static member is needed for data binding purposes.")]
    public MainViewModel Main
    {
        get
        {
            return _main;
        }
    }
}

那么从另一个视图的代码后台,你如何访问Main(MainViewModel包含所有数据列表并具有我调用的搜索方法)?或者说你应该这样做吗?

只是想知道人们是如何解决这种类型的问题的?

谢谢。


我不确定这会对您的应用程序或MVVM-Light结构或代码产生什么影响,但我遵循了WP的默认实现,并将所有我的ViewModels创建为静态的,然后根据需要从App类引用它们。-同样不确定这将如何与您特定的项目设置配合工作。 - evasilchenko
是的,默认设置将它们全部创建为静态的,这很好,但是 ViewModelLocator 类(为在设计和运行时使用的 VM 提供混合功能)不是静态类,并且没有静态视图模型。 - Bil Simser
4个回答

14

MVVM-Light 中的 ViewModelLocator 是提供为应用程序资源。因此,您仍然可以直接访问它,但语法不同。如果查看你的 App.xaml 文件,则应该在其中某个位置看到以下代码片段。

<Application.Resources>
    <vm:ViewModelLocator x:Key="Locator"
                         d:IsDataSource="True" />
</Application.Resources>

通过以下代码,在应用程序的任何位置都可以访问应用资源,因此也可以访问MainViewModel:

(App.Current.Resources["Locator"] as ViewModelLocator).Main

这对于任何应用程序资源都有效。


4

如果您按照模板创建了ViewModelLocator,则具有静态引用ViewModels。 mvvmlocatorproperty代码片段会创建ViewModel属性,如下所示。 这意味着您只需实例化新的ViewModelLocator即可在代码后面的按钮单击中定位ViewModels。 无论ViewModelLocator的不同实例如何,它始终是相同的viewmodels。


正在研究这个问题。代码片段的输出结果与创建新项目时得到的结果不符,因此我可能需要进行一些调整。在定位器中,每个创建的 ViewModel 都有一个静态引用,所以这可能有效。今晚稍后回来看看是否可行。 - Bil Simser
刚刚检查了一下,一旦正确的代码与ViewModelLocator放置在一起,Martin是正确的。创建任何ViewModelLocator实例都允许您在设计模式下访问其静态属性,同时保持其可混合性。 - Bil Simser

2
要从您的代码中访问MainViewModel,您可以将以下属性添加到您的类中:
public ViewModel.MainViewModel myContext { get { return (DataContext as ViewModel.MainViewModel); } }

那么您只需要使用 myContext.[任何内容] 就可以了。


这个可能有效,我打算先尝试使用片段来调整主视图模型,但也会试一下这个。当然现在的问题是哪种技术更好? - Bil Simser
我在我的App.xaml.cs中使用了这个静态引用,它将允许您从任何具有应用程序using语句的代码后台文件中访问您的MainViewmodel实例。 - Lance McCarthy

0
你可以直接使用ViewModelLocator.MainViewModelStatic。MVVMLight的默认模板为每个ViewModel都提供了一个静态属性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接