gpt4 book ai didi

c# - Xamarin Forms 访问所有 View 模型

转载 作者:行者123 更新时间:2023-11-30 21:43:41 24 4
gpt4 key购买 nike

我在我的项目中使用 ViewModelLocator。

我在 app.xaml 中的 ResourceDictionary 中执行 ViewModelLocator 的 BindingContent

我的代码:

App.xaml

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controlsHelpers="clr-namespace:MyProj.Source.Helpers.UIHelper.ControlsHelpers;assembly=MyProj"
xmlns:configuration="clr-namespace:MyProj.Source.Configuration;assembly=MyProj"
x:Class="MyProj.App">
<Application.Resources>

<ResourceDictionary>
<configuration:ViewModelLocator x:Key="ViewModelLocator"/>
</ResourceDictionary>
</Application.Resources>
</Application>

ViewModelLocator.cs

 public class ViewModelLocator
{
public LoginViewModel LoginViewModel { get; set; }
public SignUpViewModel SignUpViewModel { get; set; }


public ViewModelLocator()
{
LoginViewModel = new LoginViewModel();
SignUpViewModel = new SignUpViewModel();
}
}

LoginViewModel.cs

public class LoginViewModel : AbstractViewModel
{

private MyModel UserData { get; set; } = new MyModel();


private bool _isSignRequired;


public bool IsSignRequired
{
get { return _isSignRequired; }
set
{
if (value == _isSignRequired) return;
_isSignRequired = value;
OnPropertyChanged();
}
}

public string UserName
{
get { return UserData.UserName; }
set
{
if (value == UserData.UserName) return;
UserData.UserName = value;
OnPropertyChanged();
}
}

public string Password
{
get { return UserData.Password; }
set
{
if (value == UserData.Password) return;
UserData.Password = value;
OnPropertyChanged();
}
}

}

SignUpViewModel.cs

public class SignUpViewModel : AbstractViewModel
{
private string _checkUserResultImage;

public MyModel UserData { get; set; } = new MyModel();

public string Phone
{
get { return UserData.Phone; }
set
{
if (UserData.Phone != null && value == UserData.Phone) return;
UserData.Phone = value;
OnPropertyChanged();
}
}

public string UserName
{
get { return UserData.UserName; }
set
{
if (UserData.UserName != null && value == UserData.UserName) return;
UserData.UserName = value;
OnPropertyChanged();
}
}

public string Password
{
get { return UserData.Password; }
set
{
if (UserData.Password != null && value == UserData.Password) return;
UserData.Password = value;
OnPropertyChanged();
}
}

public string Email
{
get { return UserData.Email; }

set
{
if (UserData.Email != null && value == UserData.Email) return;
UserData.Email = value;
OnPropertyChanged();
}
}

public string CheckUserResultImage
{
get { return _checkUserResultImage; }
set
{
if (value == _checkUserResultImage) return;
_checkUserResultImage = value;
OnPropertyChanged();
}
}


public Command SignUpCommand
{
get
{
return new Command(async () =>
{
//Here I want to get data field from LoginViewModel


});
}
}
}

我想从 SignUpViewModel 中的 LoginViewModel 获取数据。

我该怎么做?

最佳答案

你的问题比我想你可能意识到的要微妙和复杂一点。

您在问“如何从我的 LoginViewModel 获取信息到我的 SignupViewModel?”有很多不同的方法可以做到这一点!不幸的是,其中许多都是不好的,并且违背了 MVVM 设计模式的目的。 MVVM 鼓励组件解耦和封装。

最明显(也是最糟糕)的方法是简单地在 SignupViewModel 中获取对 LoginViewModel 的引用,并直接引用其属性。不幸的是,这是一个非常脆弱的解决方案,并且强制依赖于您的 LoginViewModel。如果您的登录流程发生变化,您的 SignupViewModel 必须随之改变。不理想。

因此,为了避免组件的紧密耦合,您需要做一些更简单的事情:仅传递您感兴趣的数据。也有很多方法可以做到这一点,例如事件、参数传递或消息系统。

事件工作正常,但我不建议使用它们,因为它再次强制您的 SignupViewModel 直接依赖于您的 LoginViewModel。不过,如果您对此表示满意,它就可以工作。

参数传递可能是最轻量级的解决方案,但不幸的是,Xamarin Forms 不支持开箱即用。我以前实现过它,但它涉及一些工作。

允许您订阅和发布任意消息的消息传递系统是一种非常常见的解决方案(事实上,事件实际上是一种特定形式)。如果您正在寻找一个快速的直接解决方案,我认为这可能是您最好的选择,因为 MVVM Light Toolkit随附的 Messenger 正是这样做的。即使你不使用那个确切的实现,从根本上说,你也想做这样的事情:

假设您的 Messenger 实现了如下所示的某种界面:

public interface IMessenger
{
Publish<TMessage>(TMessage);
Subscribe<TMessage>(object, Action<TMessage>); //the object here should be a reference to the recipient.
}

然后你的实现可能看起来像这样:

您将使用此类传递信息:

public class LoginMessageArgs
{
public string Username {get; private set;}
//whatever other information this message needs to contain...
}

您的登录 View 模型:

public class LoginViewModel : AbstractViewModel
{
//all your properties go here...

IMessenger messengerReference;

public LoginViewModel()
{
//Get a reference to your Messenger somehow. Maybe it's a singleton in ViewModelLocator?
messengerReference = ViewModelLocator.Messenger;
}

//Maybe you call this method when you navigate away from the LoginViewModel, or whenever it makes sense to send this information to your SignupViewModel.
private void PassLoginInformation()
{
messengerReference.Publish<LoginMessageArgs>(new LoginMessageArgs { Username = this.Username }); //etc
}
}

您的 SignupViewModel:

public class SignUpViewModel : AbstractViewModel
{

//all your properties go here...

public SignupViewModel()
{
//Get a reference to your Messenger somehow. Maybe it's a singleton in ViewModelLocator?
IMessenger messengerReference = ViewModelLocator.Messenger;
messenger.Register<LoginMessageArgs>(this, OnLoginMessageReceived);
}

private OnLoginMessageReceived(LoginMessageArgs message)
{
//Do stuff with your message
}
}

哇!希望对您有所帮助。

关于c# - Xamarin Forms 访问所有 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41458596/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com