我建立了一个兼容mvvm的可正常使用的wpf应用程序。我有一个窗口,在其中我通过一个属性(名为CurrentHomeView的公共对象)进行控制,该属性将显示Datatemplate。例如:如果我的属性等于LoginViewModel,则窗口将显示LoginControl,它是一个UserControl。到目前为止,一切都很好。 现在,我想使用此系统并在xamarin应用程序中使用它。但是我在wpf应用程序中实现它的方式似乎不是xamarin中正确的方法。
我该怎么办,它将以相同的方式工作?
提前坦克;)
您将在我的代码中,到目前为止我已经建立的。我的ContantPage没有更改contant:D
我的班级来管理我的财产的价值:
namespace Core.ApplicationStartUp
{
public class StartUp : BindableBase
{
LoginViewModel _loginViewModel;
private bool _isNewUser;
private object _currentMainView;
public object CurrentMainView
{
get => _currentMainView;
set => SetProperty(ref _currentMainView, value);
}
public bool IsNewUser
{
get => _isNewUser;
set => SetProperty(ref _isNewUser, value);
}
public StartUp()
{
_isNewUser = SearchUserData();
if (!IsNewUser)
LoadLoginControl();
}
private bool SearchUserData()
{
return false;
}
private void LoadLoginControl()
{
_loginViewModel = new LoginViewModel(this);
bool isIn = _loginViewModel.CheckStatus();
if (!isIn)
CurrentMainView = _loginViewModel;
else
_loginViewModel.Login();
}
}
}
WPF应用程序中的“我的窗口”:
<Window.Resources>
<DataTemplate DataType="{x:Type loginCore:LoginViewModel}">
<loginControl:LoginControl/>
</DataTemplate>
<DataTemplate DataType="{x:Type registrationCore:RegistrationViewModel}">
<registrationControl:RegistrationControl/>
</DataTemplate>
<DataTemplate DataType="{x:Type navigationCore:NavigationViewModel}">
<navigationControl:NavigationControl/>
</DataTemplate>
</Window.Resources>
<Border BorderThickness="0.5" BorderBrush="White">
<DockPanel LastChildFill="True">
<ContentControl Content="{Binding CurrentMainView, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
</DockPanel>
</Border>
这是我在Xamarin中的Page,应该使用相同的Class来映射活动视图:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:navigationControl="clr-namespace:Mobile.Areas.Navigation"
xmlns:navigationCore="clr-namespace:Core.Areas.Navigation;assembly=Core"
xmlns:registrationCore="clr-namespace:Core.Areas.Registration;assembly=Core"
xmlns:registrationControl="clr-namespace:Mobile.Areas.Registration"
xmlns:loginCore="clr-namespace:Core.Areas.Login;assembly=Core"
xmlns:loginControl="clr-namespace:Mobile.Areas.Login"
x:Class="Mobile.MainWindow">
<ContentPage.Resources>
<DataTemplate x:DataType="{x:Type loginCore:LoginViewModel}"
x:Key="LoginControl">
<loginControl:LoginControl/>
</DataTemplate>
<DataTemplate x:DataType="{x:Type registrationCore:RegistrationViewModel}"
x:Key="RegistrationControl">
<registrationControl:RegistrationControl/>
</DataTemplate>
<DataTemplate x:DataType="{x:Type navigationCore:NavigationViewModel}"
x:Key="NavigationControl">
<navigationControl:NavigationControl/>
</DataTemplate>
</ContentPage.Resources>
<StackLayout>
<ContentView Content="{Binding CurrentMainView}"/>
</StackLayout>
</ContentPage>
我没有任何异常或错误。此外,输出中没有任何信息。
答案 0 :(得分:0)
Xamarin.Forms中没有等效于WPF ContentControl
的文件。您可以按照建议的here创建自定义ContentView
:
public class ContentPresenter : ContentView
{
public static readonly BindableProperty ItemTemplateProperty = BindableProperty.Create("ItemTemplate", typeof(DataTemplate), typeof(ContentPresenter), null, propertyChanged: OnItemTemplateChanged);
private static void OnItemTemplateChanged(BindableObject bindable, object oldvalue, object newvalue)
{
var cp = (ContentPresenter)bindable;
var template = cp.ItemTemplate;
if (template != null)
{
var content = (View)template.CreateContent();
cp.Content = content;
}
else
{
cp.Content = null;
}
}
public DataTemplate ItemTemplate
{
get
{
return (DataTemplate)GetValue(ItemTemplateProperty);
}
set
{
SetValue(ItemTemplateProperty, value);
}
}
}
答案 1 :(得分:0)
据我了解,您想在Xamarin应用程序中从WPF应用程序重用ViewModels-这是可行的,但并不容易。
您在WPF中进行视图切换的方式是可行的,并且可以,但是当您要使用多平台时,并不是“如何完成”。
您应该做的第一件事是确保ViewModels与平台无关-将它们全部放入PCL中。正确的MVVM应用程序即使没有附加任何视图也应该能够运行并执行操作-这包括切换活动的ViewModel。
您可以通过使用导航/路由服务来实现这一点-大多数MVVM框架都具有该功能。基本上,您需要显示一些ViewModel -如果您想学习很多东西,编写自己的东西,否则要使用现有的东西,再浪费一次的时间是不值得的。 VM的显示方式取决于程序在哪个平台上运行-从VM的角度来看应该没有什么区别。尽管如此,您仍需要为每个平台使用单独的视图(WPF中的用户控件,表单中的页面)。
我认为最好的MVVM框架之一是ReactiveUI,它是用Xamarin编写的,因此速度快,启动时间短等。它也可用于大多数平台:WPF,WinForms,Windows Universal Apps,甚至还有Avalonia和其他一些。 RxUI甚至支持开箱即用的视图激活,这非常方便。另外,一旦您做出反应,就无法退回:)
This文章介绍了路由概念的基础。
从那里快乐地挖掘:)