C# 如何将列表转换为隐式运算符类型
我试图学习MVVM,在我的ViewModel中,我添加了隐式操作符,它将模型转换为ViewModel,反之亦然,但现在的问题是如何将模型列表转换为ViewModel列表 下面是我尝试用于列表转换的结构代码,但它不起作用: Person.csC# 如何将列表转换为隐式运算符类型,c#,.net,wpf,mvvm,C#,.net,Wpf,Mvvm,我试图学习MVVM,在我的ViewModel中,我添加了隐式操作符,它将模型转换为ViewModel,反之亦然,但现在的问题是如何将模型列表转换为ViewModel列表 下面是我尝试用于列表转换的结构代码,但它不起作用: Person.cs class Person { public string FirstName { get; set; } public string LastName { get; set; } } PersonViewModel.cs class Pe
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
PersonViewModel.cs
class PersonViewModel : Person
{
public string FullName { get; set; }
public static implicit operator List<PersonViewModel>(IList<Person> person)
{
if (person == null)
return null;
return person.Select(c => new PersonViewModel(c)).ToList(); // This is not working
}
public static implicit operator PersonViewModel(Person person)
{
return new PersonViewModel
{
FirstName = person.FirstName,
LastName = person.LastName,
};
}
public static implicit operator Person(PersonViewModel personViewModel)
{
return new Person
{
FirstName = personViewModel.FirstName,
LastName = personViewModel.LastName,
};
}
}
类PersonViewModel:Person
{
公共字符串全名{get;set;}
公共静态隐式运算符列表(ILST人员)
{
if(person==null)
返回null;
return person.Select(c=>newPersonViewModel(c)).ToList();//这不起作用
}
公共静态隐式运算符PersonViewModel(Person)
{
返回新PersonViewModel
{
FirstName=person.FirstName,
LastName=person.LastName,
};
}
公共静态隐式运算符Person(PersonViewModel PersonViewModel)
{
换人
{
FirstName=personViewModel.FirstName,
LastName=personViewModel.LastName,
};
}
}
尝试使用Cast
person.Cast<PersonViewModel>().ToList();
person.Cast().ToList();
更新
这将给您带来其他错误。您可以使用扩展方法,并在需要时显式调用。类似这样的情况(确保最终检查空值)
班级人员
{
公共字符串名{get;set;}
公共字符串LastName{get;set;}
}
类PersonViewModel:Person
{
公共字符串全名{get;set;}
}
静态类转换助手
{
公共静态Person-ToPerson(此PersonViewModel pvm)
{
返回新人()
{
FirstName=pvm.FirstName,
LastName=pvm.LastName
};
}
公共静态PersonViewModel TopPersonViewModel(此人p)
{
返回新的PersonViewModel()
{
FirstName=p.FirstName,
LastName=p.LastName
};
}
公共静态IEnumerable TopPersonViewModels(IEnumerable persons)
{
返回persons.Select(p=>p.ToPersonViewModel());
}
}
很抱歉,您的“MVVM模式”对我来说似乎有点奇怪。这是我对MVVM模式的理解 编辑作为@Mark Feldman评论的答案
若包装看起来不必要或代码膨胀,那个么可以跳过“ModelWrapper”,并且可以由模型本身实现
INotifyPropertyChanged
。
如果您不关心向视图通知模型属性的更改,则不需要将模型集合转换为ViewModels集合。ViewModel将包含ObservableCollection类型的属性
class PersonViewModel
{
public ObservableCollection<Person> Persons { get; set; }
//if you don't care about tracking changes of collection(Add, Remove)
//then use only List<Person> without any conversions
public List<Person> Persons { get; set; }
}
然后通过构造函数以同样的方式将模型列表转换为ViewModel集合Ok这可能是个愚蠢的问题,但您是否缺少“新”关键字?@ViktorLaCroix编辑了我的帖子,但这次它抱怨“PersonViewModel不包含带1个参数的构造函数”它是否包含接受1个参数的构造函数D如果不是,并且您不希望这样,那么您应该执行类似person.Select(x=>newpersonviewmodel(){FullName=c.FullName})的操作@ViktorLaCroix和c.FullName来自哪里?@zee这是你的代码,不是我们的。啊,我的错,编辑了我的帖子。现在给出的错误是“PersonViewModel不包含接受1个参数的构造函数”。啊,好的:)更新了我的答案。但是,我认为最终会出现更多错误,因为您不能在那里使用该接口,并且可以在基类之间定义隐式运算符。tnx,我尝试过强制转换,但现在它抱怨“用户定义的转换必须转换为封闭类型或从封闭类型转换为封闭类型”。为什么要使用运算符重载,而不仅仅是创建一些映射帮助程序?我已经想过使用映射帮助程序,但我想当我有这么多模型和ViewModel时,维护起来会比较困难,因此,最好对每个ViewModel都使用隐式运算符,这将使代码看起来更干净。从我所能收集到的信息来看,问题不在于如何通过视图模型向视图公开模型属性,而在于如何保持视图模型集合与其关联的模型集合同步,而无需经历代码膨胀。我个人并不认为INPC是视图-模型-视图关系的唯一要求,因此我倾向于将其添加到模型中,同时用于属性和集合。在这之后,视图模型订阅其模型的CollectionChanged事件,同时仍按此处所示公开属性,这是一个简单的问题。@MarkFeldman,我创建包装器只是因为OP通过继承公开了从模型到视图模型的所有属性。如果您在评论中描述,请参见我的更新answer@MarkFeldman,据我所知,这个问题与同步模型的集合和viewmodel的集合无关,因为在另一种类型中转换一种类型(作为OP的方法)将始终创建新实例。
//Model
class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
//ModelWrapper which implements INotifyPropertyChanged if Model doesn't
//Here you can add additional properties which will serve a View's needs
class PersonModelWrapper
{
private Person _Model;
//Through this constructor you will create instance of modelwrapper
//without any conversions
public PersonModelWrapper (Person model)
{
_Model = model;
}
public string FirstName
{
get
{
return _Model.FirstName;
}
set
{
_Model.FirstName = value;
}
}
public string LastName
{
get
{
return _Model.LastName;
}
set
{
_Model.LastName = value;
}
}
public string FullName
{
get
{
return _Model.FirstName + " " _Model.LastName;
}
}
//Through this property you will always access current model property
//without conversions
public Person Model { get { return _Model; }}
}
//ViewModel which used as DataContext in the View
class PersonViewModel
{
private PersonModelWrapper _Wrapper;
public string Wrapper
{
get
{
return _Wrapper;
}
set
{
_Wrapper = value;
}
}
}
class PersonViewModel
{
public ObservableCollection<Person> Persons { get; set; }
//if you don't care about tracking changes of collection(Add, Remove)
//then use only List<Person> without any conversions
public List<Person> Persons { get; set; }
}
public class PersonViewModel: INotifyPropertyCahnged
{
private Person _Model;
public Person Model
{
get { return _Model; }
set
{
if(Equals(_Model, value) == true)
return;
_Model = value;
this.RaisePropertyChanged();
}
public String FullName {get {return _ModelFirstName + " " + _Model.LastName; }}
public PersonViewModel(Person model)
{
_Model = model;
}
}
}