我想在Xamarin Forms应用程序中使用MVVM模式打开一个新的模态窗口。我已经研究过用MVVM模式打开一个新窗口,这让我走得很远,但是关于Xamarin窗体中的窗口,他们需要引用当前页面(视图)来打开一个新窗口(新视图) 。这迫使我从我的viewModel向我的窗口工厂传递对当前页面(视图)的引用,以从中启动新窗口。这违反了MVVM。我的目标是从我的viewModel中删除对视图的任何引用。这是我的问题,我该怎么做?我的代码恰好是一个模态窗口,但普通的窗口也需要引用它所启动的页面。这是我的代码,你会看到我的意思:
Window Factory(查看CreateNewWindow方法):
public interface IWindowFactory
{
void CreateNewWindow();
}
public class ProductionWindowFactory: IWindowFactory
{
Page launchFromPage;
BackLogViewModel viewModel;
public ProductionWindowFactory(BackLogViewModel ViewModel, Page page)
{
viewModel = ViewModel;
launchFromPage = page;
}
public void CreateNewWindow()
{
AddStoryPage window = new AddStoryPage (new AddStoryViewModel (viewModel));
launchFromPage.Navigation.PushModalAsync (window);
}
}
}
ViewModel打开一个新的模态窗口(特别注意AddTask命令):
public class BackLogViewModel : INotifyPropertyChanged
{
private IWindowFactory m_windowFactory;
public void DoOpenNewWindow()
{
m_windowFactory.CreateNewWindow();
}
public ObservableCollection<Story> AllMyStories { get; set; }
private string _updated;
public string Updated
{
get
{
return _updated;
}
set
{
_updated = value;
OnPropertyChanged ();
}
}
public Page mypage;
public BackLogViewModel (Page page)
{
Updated = DateTime.Now.ToString();
mypage = page;
AllMyStories = new ObservableCollection<Story> ();
}
public ICommand Save
{
get {
return new Command (() => {
Updated = DateTime.Now.ToString();
});
}
}
public ICommand AddTask
{
get {
return new Command ( () => {
m_windowFactory = new ProductionWindowFactory(this, mypage);
DoOpenNewWindow();
});
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs (propertyName));
}
}
private Command selectCmd;
public Command Select {
get {
this.selectCmd = this.selectCmd ?? new Command<Story>(p =>
{
var monkey = p as Story;
if (monkey == null) return;
Page z = new Views.StoryPage(p);
mypage.Navigation.PushAsync(z);
}
);
return this.selectCmd;
}
}
}
}
如何摆脱viewModel中当前页面(视图)的引用?
答案 0 :(得分:2)
此后我发现了This tutorial on navigating views from the ViewModel in Xamarin
它基本上完成了我已经在做的事情,但它不是将完整视图传递给ViewModel,而是仅传递视图的INavigation接口,并使用它来导航。它声称它可以被认为是违反了MVVM,但是有了这样的态度,因此,我怀疑是因为没有明显和简单的替代方案存在。可能有一些替代方案没有从ViewModel引用视图的任何部分,但为了继续前进,我选择了这个简单的解决方案。我保留了我的窗口工厂,以便不在ViewModel中指定构建的具体窗口。