从另一个ViewModel设置ViewModel中的属性

3
我想在导航到与该视图模型相关联的页面之前,从另一个视图模型向视图模型传递一个值。 以前我是先将值传递给视图,然后再传递给视图模型。这似乎是一种笨拙的做法。 我不使用任何框架,所以这不是一个选项。 目前该属性被设置为静态,这个方法可以工作但我不确定这是否是良好的实践。 代码如下:
视图模型1:
以下命令打开新页面:
public void OpenRouteDetails()
{
   RouteStopPopOverViewModel.RouteName = "TestRoute";
   App.Page.Navigation.PushAsync(new RouteStopPopOverView());            
}

View model 2: (RouteStopPopOverViewModel)

public static string RouteName { get; set; }

这样做确实可以实现,但我希望避免使用静态方式来实现。 有没有一些方法可以设置RouteName属性而不使用静态或将其通过视图传递给视图模型。 我看到了一些关于此问题的答案,但它们似乎没有清晰地回答这个问题。
4个回答

2

在视图模型之间共享控制器类。
同一个实例必须提供给两个视图模型的构造函数。
这样你就可以在两个视图模型中设置值并监听事件。
控制器类成为中间人。

public class SharedController : IControlSomething
{
    private string _sharedValue;

    public string SharedValue
    {
        get => _sharedValue;
        set
        {
            if (_sharedValue == value)
                return;

            _sharedValue = value;
            OnSharedValueUpdated();
        }
    }

    public event EventHandler SharedValueUpdated;

    protected virtual void OnSharedValueUpdated()
    {
        SharedValueUpdated?.Invoke(this, EventArgs.Empty);
    }
}

public class ViewModel1
{
    private readonly IControlSomething _controller;

    public ViewModel1(IControlSomething controller)
    {
        // Save to access controller values in commands
        _controller = controller;
        _controller.SharedValueUpdated += (sender, args) =>
        {
            // Handle value update event
        };
    }
}

public class ViewModel2
{
    private readonly IControlSomething _controller;

    public ViewModel2(IControlSomething controller)
    {
        // Save to access controller values in commands
        _controller = controller;
        _controller.SharedValueUpdated += (sender, args) =>
        {
            // Handle value update event
        };
    }
}

1

这里有一个示例,您可以轻松地通过导航实现您的要求

public class ViewModelFrom : BaseViewModel
{
    async Task ExecuteCommand()
     {
        string routeName="value to trasfer";
        Navigation.PushAsync(new View(routeName));
     }
}


public partial class View : ContentPage
{
    public View(string routeName)
    {
        InitializeComponent();
        BindingContext = new ViewModelTo(routeName);
     }
}

public class ViewModelTo : BaseViewModel
{
    public string RouteName { get; set; }

    public ViewModelTo(string routeName)
    {
         RouteName=routeName;
    }
}

我不想通过视图传递参数到视图模型中。这大多数情况下并不是我的选择,所以我的手被绑住了。这也似乎是一种笨拙的方式来处理这个问题。 - user3355961
你知道其他的方法吗? - user3355961
考虑如何在两个类之间传输数据并将其应用到此处。 - Shiwanka Chathuranga

0
如果存在层级关系,您可以将其表达为它们的共同父节点。
public class Route
{
    private string Name;
}

public class RouteSelectedArgs : EventArgs
{
    public Route Selected { get; set; }
}

public interface IRouteSelection
{
    event EventHandler<RouteSelectedArgs> RouteSelected;
}

public interface IRouteDetails { }

public class RouteWizard
{
    public UserControl view { get; set; }

    private IRouteSelection _selection;
    private IRouteDetails _details;

    public RouteWizard(IRouteSelection selection, IRouteDetails details)
    {
        _selection = selection;
        _details = details;
        _selection.RouteSelected += Selection_RouteSelected;
        view = MakeView(_selection);
    }

    private void Selection_RouteSelected(object sender, RouteSelectedArgs e)
    {
        _selection.RouteSelected -= Selection_RouteSelected;
        view = MakeView(_details, e.Selected);

    }

    private UserControl MakeView(params object[] args)
    {
        ////magic
        throw new NotImplementedException();
    }
}

谢谢,我会看一下这个。 - user3355961

0

由于您正在使用MVVM模式,因此可以使用众多MVVM框架之一来实现此目的。

我使用FreshMvvm,它允许我像这样在视图模型之间传递参数

await CoreMethods.PushPageModel<SecondPageModel>(myParameter, false);

然后在SecondPageModel中,我可以在Init方法中访问参数

private MyParamType _myParameter;

public override void Init(object initData)
{
    base.Init(initData);

    var param = initData as MyParamType;
    if (param != null)
    {
        _myParameter = param;
    }
}

您可以在这里找到有关FreshMvvm的更多详细信息,尽管大多数MVVM框架具有类似的功能。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接