如何在另一个ViewModel中访问一个ViewModel属性/ Data

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

我用谷歌搜索了很多次,并在很多论坛上搜索过,但我没有得到我想要的东西。

简单来说,我有主窗口,首先我应该显示LoginUserControl,当用户点击LoginUserControl中的按钮时,它应该移动到GameUserControl,再次当他点击GameUserControl中的按钮时,它应该移动到LoginUserControl

我正在使用MVVM模式和Unity for DependencyInjection(当我搜索时,我听说很容易通过它维护实例)。

这是我到现在为止所尝试的:

的MainView:

 <Window.DataContext>
        <local:MainWindowViewModel />
    </Window.DataContext>
    <Grid>
        <ContentControl Content="{Binding ShowControl}" />
    </Grid>

MainViewModel:

 class MainWindowViewModel : Bindable, IMainViewModel 
{
    private UserControl showControl;
    public UserControl ShowControl
    {
        get
        {
            if (showControl == null)
                showControl = App.Container.Resolve<LoginView>();
            return showControl;
        }
        set
        {
            SetProperty(ref showControl, value);
        }
    }
}

LoginView:

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="0.5*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Label Grid.Row="0" Content="{Binding Display}" />
    <Button Grid.Row="1" Content="Navigate to Game View" Command="{Binding Navigae}" />
    <TextBox Text="{Binding MyData, Mode=TwoWay}" Grid.Row="2" Margin="52,24,76,31" />
</Grid>

LoginView.cs:

public LoginView(IMainViewModel mainViewModel)
    {
        this.DataContext = new LoginViewModel(mainViewModel);
        InitializeComponent();
    }

LoginViewModel:

public class LoginViewModel : Bindable
{
    // Bindable which implements INotifyPropertyChanged Event

    IMainViewModel mainViewModel;
    public LoginViewModel(IMainViewModel mainViewModel)
    {
        this.mainViewModel = mainViewModel;
        this.Navigae = new RelayCommand(execute, canExecute);
        display = "login view";
        myData = "Gopi ";
    }

    private bool canExecute(object arg)
    {
        return true;
    }

    private void execute(object obj)
    {
       // mainViewModel.ShowControl = App.Container.Resolve<GameView>();
       // here I want to access the ShowControl property from MainViewModel and update it
    }

    public ICommand Navigae
    {
        get; set;
    }

    private string display;

    public string Display
    {
        get
        {
            return display;
        }
        set
        {
            SetProperty(ref display, value);
        }
    }

    private string myData;

    public string MyData
    {
        get
        {
            return myData;
        }
        set
        {
            myData = value;
        }
    }
}

以同样的方式,我有GameView,GameView.cs和GameViewModel(只有名称更改w.r.t. LoginView)

IMainViewModel :(它用作我在一些例子中看到的Repository)

public interface IMainViewModel
{

}

我正在使用unity,因为每次单击按钮时我都不想创建新实例。当我们使用unity时,它将首次创建实例并在以后使用它。

这是App.cs的代码:

public partial class App : Application
{
    private static IUnityContainer _container;
    protected override void OnStartup(StartupEventArgs e)
    {
        base.OnStartup(e);
        ConfigureContainer();
        Application.Current.MainWindow = _container.Resolve<MainWindow>();
        Application.Current.MainWindow.Show();
    }

    private void ConfigureContainer()
    {
        _container = new UnityContainer();
        _container.RegisterType<IMainViewModel, MainWindowViewModel>(new ContainerControlledLifetimeManager());
    }

    public static IUnityContainer Container
    {
        get
        {
            return _container;
        }
    }
}

任何人都可以从这一点指导我。

提前致谢 :)

c# wpf mvvm unity-container
1个回答
1
投票

我建议你考虑一下viewmodel的第一个导航。

作为旁观/观察:

将MainWindowViewModel解析为统一似乎是因为你想将它传递给其他视图模型。这就是你传递给子视图模型的全部内容。即使您打算模拟mainwindowviewmodel,也可以通过在测试代码中实例化mock来实现。

在这个阶段,你的依赖注入似乎使事情变得复杂。

/ 在旁边。

考虑一下这个方法:

https://social.technet.microsoft.com/wiki/contents/articles/52485.wpf-tips-do-not-use-frame-and-page-for-navigation.aspx

MainWindowViewmodel控制导航。你想从像样本的代码中的子控件中的按钮那样做吗?没问题。您可以对命令使用relativesource绑定,并将子控件中的按钮绑定到mainwindowviewmodel中的命令。如果需要某些数据,可以从子视图模型中绑定命令参数。

那个mainwindowviewmodel然后实例化任何子视图模型而不是它们的用户控件。如果仍然需要,Mainwindowviewmodel可以传递对自己的引用。

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