我用谷歌搜索了很多次,并在很多论坛上搜索过,但我没有得到我想要的东西。
简单来说,我有主窗口,首先我应该显示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;
}
}
}
任何人都可以从这一点指导我。
提前致谢 :)
我建议你考虑一下viewmodel的第一个导航。
作为旁观/观察:
将MainWindowViewModel解析为统一似乎是因为你想将它传递给其他视图模型。这就是你传递给子视图模型的全部内容。即使您打算模拟mainwindowviewmodel,也可以通过在测试代码中实例化mock来实现。
在这个阶段,你的依赖注入似乎使事情变得复杂。
/ 在旁边。
考虑一下这个方法:
MainWindowViewmodel控制导航。你想从像样本的代码中的子控件中的按钮那样做吗?没问题。您可以对命令使用relativesource绑定,并将子控件中的按钮绑定到mainwindowviewmodel中的命令。如果需要某些数据,可以从子视图模型中绑定命令参数。
那个mainwindowviewmodel然后实例化任何子视图模型而不是它们的用户控件。如果仍然需要,Mainwindowviewmodel可以传递对自己的引用。