在 VM 中实例化类是否符合 MVVM ?如果是这样,还能怎么样?



我有一个内容页面和一个内容视图,其中的内容属性绑定到视图模型

主页: `

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage x:Class="MvvM.Views.MainPage"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MvvM.Views"
xmlns:vm="clr-namespace:MvvM.ViewModels">
<!--  ViewModel BindingContext  -->
<ContentPage.BindingContext>
<vm:MainViewModel />
</ContentPage.BindingContext>
<Grid>
<Grid.RowDefinitions>
<!--  Header Row  -->
<RowDefinition Height="50" />
<!--  ContentView Row  -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<!--  Header  -->
<Grid Grid.Row="0"
BackgroundColor="CornflowerBlue"
VerticalOptions="FillAndExpand">
<!--  Button On Header  -->
<Button Command=""
Text="Page Switch"
VerticalOptions="Center">
<Button.GestureRecognizers>
<TapGestureRecognizer Command="TapGestureCommand" />
</Button.GestureRecognizers>
</Button>
</Grid>
<!--  Content Container  -->
<Grid Grid.Row="1" VerticalOptions="Center">
<ContentView Content="{Binding DisplayPage}" />
</Grid>
</Grid>
</ContentPage>

'

视图模型:

`using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Text;
using MvvM.Views;
using Xamarin.Forms;
namespace MvvM.ViewModels
{
public class MainViewModel :INotifyPropertyChanged
{
public MainViewModel()
{
DisplayPage = new Views.MainPage();
}
private ContentPage _displayPage;
public ContentPage DisplayPage
{
get { return _displayPage; }
set 
{
if (value != _displayPage)
{
_displayPage = value;
}
}
}

private ContentView _contentToDisplayView;
public ContentView SelectedView
{
get => _contentToDisplayView;
set
{
_contentToDisplayView = value;
OnPropertyChanged();
} 
}
public Command TapGestureCommand
{
get
{
return new Command(TapGesture);
}
}
private void TapGesture()
{
_contentToDisplayView = new RedView();
_displayPage.Content = _contentToDisplayView.Content;
OnPropertyChanged();
}
#region PropertyChangedHandler
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}`

第二个页面名为"红页"想要访问内容

'

<?xml version="1.0" encoding="utf-8" ?>
<ContentView x:Class="MvvM.Views.RedView"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:vm="clr-namespace:MvvM.ViewModels"
BindingContext="vm:MainViewModel">
<ContentView.Content>
<Grid Width="*"
Height="*"
BackgroundColor="Red" />
</ContentView.Content>
</ContentView> `

我想要的结果是红页上的内容视图内容显示在主页内容视图中。

  • 是否在视图模型 MVVM 投诉中创建红页实例?(我觉得这会将视图与视图模型紧密绑定?

    • 我还能如何将红页上的内容属性放入视图模型中?(无法绑定它并在其中设置元素,因为您只能设置内容属性一次)

理想情况下,您希望 ViewModel 对视图一无所知,反之亦然,因此从这个角度来看,这不是您想要的。

为了克服这个问题,您需要视图模型到视图模型导航。因此,您只需指定要转到的视图模型,即可加载关联的视图。您可以手动实现这一点,并且根据您选择的实现,您将有某种方法解析链接到该 ViewModel 的视图。

一种方法是命名约定和反射。这意味着您命名所有页面如下:

  • 我的页面
  • 您的页面
  • 我们的页面

以及所有视图模型,例如:

  • 我的页面模型
  • 您的页面模型
  • 我们的页面模型

然后通过反射,您可以简单地去除"模型"后缀并从那里解析页面。请注意,我使用页面和页面模型命名,但当然这也适用于视图和视图模型。完成后,您仍然必须考虑往返此视图的导航,是否为模式等。

虽然您可以手动实现所有这些,但可能值得研究一下 MVVM 框架。例如,我刚才描述的方法就是FreshMvvm是如何做到这一点的。但是还有其他好的框架,如Prism,Exrin,MvvmCross等。

相关内容

最新更新