如何从聚合的 ViewModel 更新模型中的字符串 属性
How to update a string property in the Model from an aggregated ViewModel
我正在 WPF/MVVM 开发 GUI 应用程序。假设我有一个模型 class,它反序列化了一个(第三方)XML 文件
class Person
{
public string Name { get; set; }
public string Address { get; set; }
public string ReservationId { get; set; }
}
和一个 ViewModel,它向其 View 公开许多属性和命令来操作 Model,在本例中为字符串(例如 ReservationId):
class StringManipulatorViewModel
{
string modelString; //here's the problem
public StringManipulatorViewModel(string modelString)
{
this.modelString = modelString;
}
//Stuff to let the view manipulate the string
}
StringManipulatorViewModel 是高度可重用的,它被很多 ViewModels 使用,例如
class PersonViewModel
{
Person model;
public StringManipulatorViewModel ReservationManipulatorVM; //aggregated ViewModel
public StringManipulatorViewModel AddressManipulatorVM; //aggregated ViewModel
public PersonViewModel(Person model)
{
this.model = model;
ReservationManipulatorVM = new StringManipulatorViewModel(model.ReservationId); //here's the problem
AddressManipulatorVM = new StringManipulatorViewModel(model.Address); //here's the problem
}
}
显然将字符串作为“模型”传递给 ViewModel 是无效的,而且 C# 似乎不允许将字符串引用作为字段。
best/right 在处理字符串类型时让成员 ViewModels 操作模型的方法是什么?
谢谢
我想不出一种“正确”的方式来操作字符串作为 StringManipulatorViewModel
中的引用,一旦您将字符串作为值传递,它就与模型无关。
但是,每当 StringManipulatorViewModel
操作它时,合法更改 model
字符串值的方法是在视图模型操作字符串时在视图模型中引发 Event
,然后添加使用新值更新模型的事件处理程序:
class StringManipulatorViewModel
{
string modelString;
public event EventHandler<string> StringManipulated;
public StringManipulatorViewModel(string modelString)
{
this.modelString = modelString;
}
public ManipulateString()
{
// Manipulate the string
StringManipulated?.Invoke(this, modelString);
}
}
并且在 PersonViewModel
构造函数中:
class PersonViewModel
{
Person model;
public StringManipulatorViewModel ReservationManipulatorVM;
public StringManipulatorViewModel AddressManipulatorVM;
public PersonViewModel(Person model)
{
this.model = model;
ReservationManipulatorVM = new StringManipulatorViewModel(model.ReservationId);
AddressManipulatorVM = new StringManipulatorViewModel(model.Address);
ReservationManipulatorVM.StringManipulated += (sender, e) => model.ReservationId = e;
AddressManipulatorVM.StringManipulated += (sender, e) => model.Address = e;
}
}
您的问题是您试图引用 属性,而不是字符串字段。
但是您可以将委托传递给 属性 的 setter。
如果您也将 modelString 字段更改为 属性,则可以在更改字符串时自动调用此委托。
class StringManipulatorViewModel
{
private string modelString
{
get { return _modelString; }
set { _modelString = value; if (SetModelString != null) SetModelString(value); }
}
private string _modelString;
Action<string> SetModelString;
public StringManipulatorViewModel(string initialValue, Action<string> setModelString)
{
this.modelString = initialValue;
SetModelString = setModelString;
}
//Stuff to let the view manipulate the string
}
您像这样在 PersonViewModel 中启动 StringManipulatorViewModel:
ReservationManipulatorVM = new StringManipulatorViewModel(model.ReservationId, value => model.ReservationId = value); //here's the problem
当你想传递 属性 时,这里有一些其他的想法。
Passing properties by reference in C#
我正在 WPF/MVVM 开发 GUI 应用程序。假设我有一个模型 class,它反序列化了一个(第三方)XML 文件
class Person
{
public string Name { get; set; }
public string Address { get; set; }
public string ReservationId { get; set; }
}
和一个 ViewModel,它向其 View 公开许多属性和命令来操作 Model,在本例中为字符串(例如 ReservationId):
class StringManipulatorViewModel
{
string modelString; //here's the problem
public StringManipulatorViewModel(string modelString)
{
this.modelString = modelString;
}
//Stuff to let the view manipulate the string
}
StringManipulatorViewModel 是高度可重用的,它被很多 ViewModels 使用,例如
class PersonViewModel
{
Person model;
public StringManipulatorViewModel ReservationManipulatorVM; //aggregated ViewModel
public StringManipulatorViewModel AddressManipulatorVM; //aggregated ViewModel
public PersonViewModel(Person model)
{
this.model = model;
ReservationManipulatorVM = new StringManipulatorViewModel(model.ReservationId); //here's the problem
AddressManipulatorVM = new StringManipulatorViewModel(model.Address); //here's the problem
}
}
显然将字符串作为“模型”传递给 ViewModel 是无效的,而且 C# 似乎不允许将字符串引用作为字段。 best/right 在处理字符串类型时让成员 ViewModels 操作模型的方法是什么?
谢谢
我想不出一种“正确”的方式来操作字符串作为 StringManipulatorViewModel
中的引用,一旦您将字符串作为值传递,它就与模型无关。
但是,每当 StringManipulatorViewModel
操作它时,合法更改 model
字符串值的方法是在视图模型操作字符串时在视图模型中引发 Event
,然后添加使用新值更新模型的事件处理程序:
class StringManipulatorViewModel
{
string modelString;
public event EventHandler<string> StringManipulated;
public StringManipulatorViewModel(string modelString)
{
this.modelString = modelString;
}
public ManipulateString()
{
// Manipulate the string
StringManipulated?.Invoke(this, modelString);
}
}
并且在 PersonViewModel
构造函数中:
class PersonViewModel
{
Person model;
public StringManipulatorViewModel ReservationManipulatorVM;
public StringManipulatorViewModel AddressManipulatorVM;
public PersonViewModel(Person model)
{
this.model = model;
ReservationManipulatorVM = new StringManipulatorViewModel(model.ReservationId);
AddressManipulatorVM = new StringManipulatorViewModel(model.Address);
ReservationManipulatorVM.StringManipulated += (sender, e) => model.ReservationId = e;
AddressManipulatorVM.StringManipulated += (sender, e) => model.Address = e;
}
}
您的问题是您试图引用 属性,而不是字符串字段。
但是您可以将委托传递给 属性 的 setter。
如果您也将 modelString 字段更改为 属性,则可以在更改字符串时自动调用此委托。
class StringManipulatorViewModel
{
private string modelString
{
get { return _modelString; }
set { _modelString = value; if (SetModelString != null) SetModelString(value); }
}
private string _modelString;
Action<string> SetModelString;
public StringManipulatorViewModel(string initialValue, Action<string> setModelString)
{
this.modelString = initialValue;
SetModelString = setModelString;
}
//Stuff to let the view manipulate the string
}
您像这样在 PersonViewModel 中启动 StringManipulatorViewModel:
ReservationManipulatorVM = new StringManipulatorViewModel(model.ReservationId, value => model.ReservationId = value); //here's the problem
当你想传递 属性 时,这里有一些其他的想法。
Passing properties by reference in C#