簡體   English   中英

在另一個ViewModel中的ViewModel中設置屬性

[英]Set a Property in a ViewModel from Another ViewModel

我試圖在導航到附加到該視圖模型的頁面之前,將值從另一個視圖模型傳遞給視圖模型。 我之前曾將其傳遞給視圖,然后將其傳遞給視圖模型。 這似乎是一種笨拙的處理方式。 我沒有使用任何類型的框架,所以這不是一個選擇。 目前,該屬性已設置為static並且可以正常工作,但我不確定這是否是一種好習慣。 編碼:

查看模型1:

此命令將打開新頁面:

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

查看模型2:(RouteStopPopOverViewModel)

public static string RouteName { get; set; }

這確實有效,但是我不希望使用靜態方法來實現此目的。 有什么方法可以設置RouteName屬性,而不使用靜態屬性或通過view-> view model傳遞它。 我已經看到了一些有關此問題的答案,但他們似乎並沒有明確回答問題。

在此示例中,您可以通過導航輕松實現您的要求

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

在視圖模型之間共享控制器類。
必須在兩個視圖模型中將相同的實例提供給構造函數。
因此,您可以設置值,並在兩個視圖模型中偵聽事件。
控制器類成為中介。

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

如果存在層次結構,則可以在兩個層次結構的父級中表示。

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

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

盡管大多數MVVM框架具有相似的功能,但您可以在此處找到有關FreshMvvm的更多詳細信息

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM