WPF MVVM Lights - 具有不同参数的相同用户控件

WPF MVVM Lights - Same user control with different parameter

我有一个使用 MVVM Light 的 WPF 应用程序。
一个主视图 (+ MainViewModel) 和一个用户控件 (+ UCViewModel)。

该应用程序将有一个带有 2 个选项卡项的选项卡控件。
每个选项卡都会有一个用户控件(相同的用户控件)。

用户控制作业:加载文件内容,显示内容(并允许用户将其导出为其他格式)。

当应用程序启动时,我将读取配置文件并将文件位置(从配置文件)传递给每个用户控件(例如:File1Path、File2Path)。
我可以使用 MVVM Light Messenger.Default.Send 来完成这项工作(从 MainViewModelUCViewModel)。

我的问题是:如何区分哪个用户控件将获得哪个文件路径?

我在 ViewModelLocator 中使用 SimpleIoc.Default.Register 来注册我的 MainViewModelUCViewModel.
在注册的时候,我还没有Config文件的数据,所以我不能把它传递给UCViewModel。

我的问题有 comment/solution 吗?

方法一(采用mm8的方式)

按照 @mm8 的建议,我最终在我的 MainViewModel class 中为每个 UserControl 用法声明了 DataContext 作为属性。

示例(在 MainView xaml 中):

<v:UC Grid.Row="0" HorizontalAlignment="Stretch" Margin="10" DataContext="{Binding UC2DC}" />

但是,为了支持我的设计时间XAML intelliense 支持,我仍然使用DataContext 绑定的默认MVVM Light 方式。

示例:在 ViewModelLocator 中,

static ViewModelLocator()
{
    ....
    SimpleIoc.Default.Register<MainViewModel>();
    SimpleIoc.Default.Register<UCViewModel>();
    ....
}

public UCViewModel CM
{
    get
    {
        return ServiceLocator.Current.GetInstance<UCViewModel>();
    }
}

并且在 MainViewModel 中,

private UCViewModel _uC2DC;

public UCViewModel UC2DC
{
    get { return _uC2DC; }
    set { Set(ref _uC2DC, value); }
}

private UCViewModel _uC1DC;

public UCViewModel UC1DC
{
    get { return _uC1DC; }
    set { Set(ref _uC1DC, value); }
}

在我的 MainViewModel 中的某处,我需要创建新实例并将其放入这些属性中。

完成所有操作后,我将 delete/comment 退出用户控件默认的 MVVM Light DataContext 绑定、ViewModelLocator 的 SimpleIoc 注册和 GetInstance 属性 等,它会更改为我的 MainView 数据绑定。

我不太确定 MVVM 方式是否可行,但截至目前,它解决了我的问题。

方法二(用Marco的方式)

在 Marco 示例代码之后,我开始知道我们可以使用一个键来注册 ViewModel 的多个实例以区分它们,并且在调用 属性 时,使用该键来提取正确的实例。
下面是代码...

对于 ViewModelLocator

static ViewModelLocator()
{
    ...
    SimpleIoc.Default.Register<MainViewModel>();
    SimpleIoc.Default.Register(() => new UCViewModel(), "1");
    SimpleIoc.Default.Register(() => new UCViewModel(), "2");
    ...
}

public UCViewModel UCVM1
{
    get
    {
        return ServiceLocator.Current.GetInstance<UCViewModel>("1");
    }
}

public UCViewModel UCVM2
{
    get
    {
        return ServiceLocator.Current.GetInstance<UCViewModel>("2");
    }
}

在我的 MainView 中 XAML

<TabControl>
    <TabItem Header="Test 1">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="70"/>
                <RowDefinition Height="70"/>
            </Grid.RowDefinitions>
            <v:UC Grid.Row="0" HorizontalAlignment="Stretch" Margin="10" 
                DataContext="{Binding UCVM1,Source={StaticResource Locator}}" />
            ...
            ...
        </Grid>
    </TabItem>
    <TabItem Header="Test 2">
        <Grid Background="AliceBlue">
            <Grid.RowDefinitions>
                <RowDefinition Height="1*"/>
                <RowDefinition Height="70"/>
                <RowDefinition Height="70"/>
            </Grid.RowDefinitions>
            <v:UC Grid.Row="0" HorizontalAlignment="Stretch" Margin="10" 
                DataContext="{Binding UCVM2,Source={StaticResource Locator}}" />
            ...
            ...
        </Grid>
    </TabItem>
</TabControl>

对于这种方法,它仍然是相同的,在设计时,我们不能绑定到一个默认的 DataContext。可能这是对这种情况的妥协。