wpf 如何将视图构造函数参数传递给视图模型

vaqhlq81  于 2023-08-07  发布在  其他
关注(0)|答案(4)|浏览(172)

我有一个视图和视图模型。

MyView
{
  MyView(int id)
  {
    InitializeComponent();
  }
}

 MyViewModel
    {
     private int _id;
      public int ID
       {
        get { return _id; }
        set { _id= value; OnPropertyChanged("_id"); }
       }
    }

字符串
我将XAML上的数据上下文设置为:

<Window.DataContext>
        <vm:MyViewModel/>
</Window.DataContext>


单击按钮时,我显示的视图为:

Application.Current.Dispatcher.Invoke(() => new MyView(id).Show());


现在,如何将id从MyView(id)传递到MyViewModel.ID.

3pmvbmvn

3pmvbmvn1#

由于DataContext是在InitializeComponent()调用之后创建的,因此您可以在之后将其传递给ViewModel:

MyView
{
   MyView(int id)
   {
     InitializeComponent();
     ((MyViewModel)DataContext).ID = id;
   }
 }

字符串

gywdnpxw

gywdnpxw2#

您可以执行以下解决方案之一:

1)使用Messenger模式:

您可以使用Messenger模式,例如,如果您使用MVVMLight,您可以执行以下操作:
ViewModel中:

MyViewModel
{
     private int _id;
     public int ID
     {
        get { return _id; }
        set { _id= value; OnPropertyChanged("_id"); }
     }

     Public void InitilizeMessenger()
     {
         Messenger.Default.Register(this,"To MyViewModel", (int id) => ID = id);
     }
     public MyViewModel()
     {
        InitilizeMessenger();
     }
}

字符串
通过注册到Messenger,可以使ViewModel准备好接收消息。
在视图中执行以下操作:

MyView
{
  MyView(int id)
  {
    InitializeComponent();
    Messenger.Default.Send<int>(id,"To MyViewModel");
  }
}


广播一条消息,发送消息时附带“To MyViewModel”标签,这样MyViewModel就可以捕获它。

2)从View访问DataContext:

MyView
{
  MyView(int id)
  {
    InitializeComponent();
    ((MyViewModel)this.DataContext).ID = id;
  }
}


第二个解决方案简单明了,我给出的第一个只是为了更复杂的情况。

0x6upsns

0x6upsns3#

首先,OnPropertyChanged(“_id”)是错误的,因为_id是变量,而不是属性。您必须更改为OnPropertyChanged(“ID”)。您可以在代码隐藏中指定viewModel。

class MyView
{
      MyView(int id)
        :this(new MyViewModel(id))
      {
      }

      MyView(MyViewModel viewModel)
      {
        InitializeComponent();
        this.DataContext = viewModel;
      }
}

class MyViewModel
{
     private int _id;
     public int ID
     {
        get { return _id; }
        set { _id= value; OnPropertyChanged("ID"); }
     }
     public MyViewModel(int id)
     {
        ID=id;
     }
}

字符串

ruoxqz4g

ruoxqz4g4#

正如Doctor所说,将variable传递给viewmodel是正确的方法,而将viewmodels参数赋值是错误的:让我评论以下几点:
我认为这两种方式都是错误的。
第一个原因是视图模型在大多数情况下也被用作视图(XAML)页面的绑定/数据上下文。它必须有一个没有构造函数属性/输入变量的datacontext,即使在设置默认值时也是如此:public int maximum(int n)InputVar = null){}
第二个原因是,给其他视图模型类中的参数赋值会让它变得可怕,因为这些变量一旦被设置,当视图模型中发生其他事情时,即使没有重新分配或处理该参数,这些变量也会变成default/ null或空。这是我的项目经常遇到的问题,我想以简单的方式将数据发送到其他视图模型,但总是遇到问题。我建议使用EventAggregators:举个例子:

public class EventAggregator
{
    private static readonly EventAggregator instance = new EventAggregator();
    public static EventAggregator Instance => instance;

    private EventAggregator()
    {
    }

    public event EventHandler<ParameterEventArgs> ParameterEvent;

    public void PublishParameter(string parameter)
    {
        ParameterEvent?.Invoke(this, new ParameterEventArgs(parameter));
    }
}

public class ParameterEventArgs : EventArgs
{
    public ParameterEventArgs(string parameter)
    {
        Parameter = parameter;
    }

    public string Parameter
    {
        get;
    }
}

字符串
然后在Viewmodel A中:

public class ViewModelA
{
    public void SomeMethod()
    {
        string parameterValue = "Hello, ViewModelB!";
        EventAggregator.Instance.PublishParameter(parameterValue);
    }
}


在Viewmodel B中:

public class ViewModelB
{
    public ViewModelB()
    {
        EventAggregator.Instance.ParameterEvent += OnParameterReceived;
    }

    private void OnParameterReceived(object sender, ParameterEventArgs e)
    {
        string parameter = e.Parameter;
        // Now you can use the 'parameter' in ViewModelB.
    }
}

相关问题