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

时间:2019-02-27 12:46:11

标签: c# wpf mvvm unity-container

是的,我用Google搜索了很多遍,并在许多论坛中进行了搜索,但是我没有得到我想要的东西。

简单来说,我有一个Main窗口,首先我应该显示LoginUserControl,当用户单击LoginUserControl中存在的按钮时,它应该移至GameUserControl,当他单击单击GameUserControl中的按钮,它将移至LoginUserControl

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

这是我到目前为止尝试过的:

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(只有名称会更改为LoginView)

IMainViewModel :(它用作我在某些示例中看到的存储库)

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;
        }
    }
}

从这一点上有人可以指导我。

预先感谢:)

1 个答案:

答案 0 :(得分:1)

我建议您考虑先使用viewmodel。

顺便一提/观察:

解决MainWindowViewModel不一致的原因似乎是因为您想要将其传递给其他viewmodel。这就是您要传递给子视图模型的全部。即使您打算模拟mainwindowviewmodel,也可以通过在测试代码中实例化模拟来实现。

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

/放在一边。

请考虑以下方法:

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

MainWindowViewmodel控制导航。 您要通过示例代码中的子控件中的按钮来执行此操作?没问题。您可以在命令上使用relativesource绑定,并将子控件中的按钮绑定到mainwindowviewmodel中的命令。如果您需要子视图模型中的一些数据,则可以将其与子视图模型绑定。

然后,该mainwindowviewmodel实例化任何子viewmodel,而不是实例化它们的usercontrol。如果仍然有必要,Mainwindowviewmodel可以将引用传递给自己。