【问题标题】:Set a Property in a ViewModel from Another ViewModel从另一个 ViewModel 在 ViewModel 中设置属性
【发布时间】:2017-12-06 12:10:44
【问题描述】:

在导航到附加到该视图模型的页面之前,我正在尝试将值从另一个视图模型传递给视图模型。 我之前将它传递给视图,然后将它传递给视图模型。这似乎是一种笨拙的做事方式。 我没有使用任何类型的框架,所以这不是一个选择。 目前该属性设置为静态,这有效,但我不确定这是否是好的做法。 代码:

查看模型 1:

此命令打开新页面:

public void OpenRouteDetails()
{
   RouteStopPopOverViewModel.RouteName = "TestRoute";
   App.Page.Navigation.PushAsync(new RouteStopPopOverView());            
}

查看模型 2:(RouteStopPopOverViewModel)

public static string RouteName { get; set; }

这确实有效,但我不希望使用静态作为实现此目的的方法。 是否有某种方法可以设置 RouteName 属性而不使用静态或通过视图-> 视图模型传递它。 我已经看到了一些关于此的答案,但他们似乎没有清楚地回答问题。

【问题讨论】:

    标签: c# xamarin mvvm xamarin.forms


    【解决方案1】:

    在视图模型之间共享一个控制器类。
    必须将相同的实例提供给两个视图模型中的构造函数。
    因此,您可以在两个视图模型中设置值并监听事件。
    控制器类成为中介。

    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
            };
        }
    }
    

    【讨论】:

      【解决方案2】:

      这里是示例,您可以通过导航轻松实现您的要求

      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;
          }
      }
      

      【讨论】:

      • 我不想通过视图将参数传递给视图模型。这主要不是我的选择,所以我的双手被束缚了。这似乎也是一种笨拙的方法。
      • 你知道其他方法吗?
      • 想想你如何在 2 个类之间传输数据并将其应用到这里
      【解决方案3】:

      如果存在层次结构,您可以将其表达为父级。

      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();
          }
      }
      

      【讨论】:

      • 干杯,我会看看这个
      【解决方案4】:

      当您使用 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;
          }
      }
      

      You can find more details about FreshMvvm here 虽然大多数 MVVM 框架都有类似的功能。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-06
        • 2013-10-22
        • 2011-09-12
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多