我有一个类:
public class Car
{
public string Name { get; set; }
public int Age { get; set; }
public Wheel[] Wheels {get;set;}
}
轮子的集合可以改变
Car 的所有属性都将显示在同一个控件中
我想看看如何为这个类创建一个 ViewModel。
我是否很好地理解了 MVVM 的概念?
public class CarViewModel()
{
ObservableCollection<Wheel> _wheels{ get; set; }
Car _car {get;set;}
public ObservableCollection<Wheel> Wheels
{
get{ return this._car.Wheels;}
set{ this._car.Wheels=value}
}
public string Name
{
get{ return this._car.Name;}
set{ this._car.Name=value}
}
public int Age
{
get{ return this._car.Age;}
set{ this._car.Age=value;}
}
public CarViewModel()
{
this._car=GetCar();
}
}
}
我将我的应用程序代码粘贴到这个 MVVM 有问题的地方(我不确定实现是否良好,并且删除 Facility 不起作用。你能帮我重建这段代码吗?
Part of UserControlHotelDescription.xaml
<ListBox Grid.Column="1" ItemsSource="{Binding Path=CheckedRoomFacilities}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=IsChecked}" Click="CheckBox_Click"/>
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
public partial class UserControlHotelDescription : UserControl
{
public UserControlHotelDescription()
{
InitializeComponent();
}
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox checkBox = sender as CheckBox;
CheckableFacility checkableFacility = checkBox.DataContext as CheckableFacility;
if (checkBox.IsChecked.GetValueOrDefault())
{
((HotelDescriptionModelView)this.DataContext).RoomFacilities.Add(new Facility() { Name = checkableFacility.Name,Id=checkableFacility.Id });
}
else
{
((HotelDescriptionModelView)this.DataContext).RoomFacilities.Remove(((HotelDescriptionModelView)this.DataContext).RoomFacilities.Where(ce => ce.Id == checkableFacility.Id).First());
}
}
}
public class HotelDescriptionModelView
{
public HotelDescription HotelDescription { get; set; }
List<Facility> AvailableFacilities { get; set; }
public HotelDescriptionModelView()
{
//there is Equal to: HotelDescription =GetHotelDescription()
HotelDescription = new HotelDescription();
HotelDescription.Name = "Hilton";
List<Facility> gotFacilities = new List<Facility>();
gotFacilities.Add(new Facility() { FacilityCategory = FacilityCategory.Relax, Id = 1, Name = "Jacuzzi", FacilityType = FacilityType.Room });
gotFacilities.Add(new Facility() { FacilityCategory = FacilityCategory.Sport, Id = 2, Name = "Trash", FacilityType = FacilityType.Room });
gotFacilities.Add(new Facility() { FacilityCategory = FacilityCategory.Sport, Id = 4, Name = "Chairlift", FacilityType = FacilityType.SkiSlope });
HotelDescription.Facilities = gotFacilities.ToArray();
AvailableFacilities = new List<Facility>();
AvailableFacilities.Add(new Facility() { FacilityCategory = FacilityCategory.Relax, Id = 1, Name = "Jacuzzi", FacilityType = FacilityType.Room });
AvailableFacilities.Add(new Facility() { FacilityCategory = FacilityCategory.Relax, Id = 2, Name = "Trash", FacilityType = FacilityType.Room });
AvailableFacilities.Add(new Facility() { FacilityCategory = FacilityCategory.Relax, Id = 3, Name = "AirCondition", FacilityType = FacilityType.Room });
AvailableFacilities.Add(new Facility() { FacilityCategory = FacilityCategory.Relax, Id = 4, Name = "Chairlift", FacilityType = FacilityType.SkiSlope });
AvailableFacilities.Add(new Facility() { FacilityCategory = FacilityCategory.Relax, Id = 5, Name = "T-bar lift", FacilityType = FacilityType.SkiSlope });
}
public string Name
{
get
{
return this.HotelDescription.Name;
}
set
{
this.HotelDescription.Name = value;
}
}
public List<Facility> RoomFacilities
{
get
{
return
this.HotelDescription.Facilities.Where(
f => f.FacilityType == FacilityType.Room).ToList();
}
set
{
this.RoomFacilities = value;
}
}
public CheckableFacility[] CheckedRoomFacilities
{
get
{
return (from fl in AvailableFacilities.Where(af => af.FacilityType == FacilityType.Room).Union(RoomFacilities)
group fl by fl.Name into d
select new CheckableFacility()
{
Name = d.Key,
IsChecked = (d.Count() > 1)
}).ToArray();
}
set
{
this.CheckedRoomFacilities = value;
}
}
}
public class CheckableFacility
{
public int Id { get; set; }
public FacilityCategory ReporterFacilityCategory { get; set; }
public bool IsChecked { get; set; }
public string Name { get; set; }
}
请您参考如下方法:
您要为每个模型创建一个 ViewModel 吗?我耽心。
应该为每个 View 创建 ViewModel,它具有 View 元素可以绑定(bind)到的所有属性。
如果该属性是来自您的数据库的数据,它将作为属性存在于模型中,并且可以在不创建任何成员的情况下被 View 模型使用。否则您的 View 模型与模型无关。
创建模型后,将其放在一边。然后创建 View 。检查绑定(bind)所需的数据是什么。根据 View 的需要在 ViewModel 中创建尽可能多的属性。大多数数据将取决于模型(可能是不同的模型)或模型中数据的推导。因此创建所需的模型实例,以便可以通过 ViewModel 获取和设置它们的属性。
如果您仍然无法获得清晰的图片,请将您的看法发送给我。我将从中创建一个示例 View 模型。
更新
酒店描述模型 View :
/* This ViewModel is to serve UserControlHotelDescription */
public class HotelDescriptionModelView
{
HotelDescription _hotelDescriptionModel;
public ObservableCollection<CheckableFacilityViewModel> CheckableRoomFacilities { get; set; }
public HotelDescriptionModelView()
{
_hotelDescriptionModel = new HotelDescription();
CheckableRoomFacilities = new ObservableCollection(GetCheckableFacilities(FacilityType.Room));
}
IEnumerable<CheckableFacilityViewModel> GetCheckableFacilities(FacilityType type)
{
return (
from fl in AvailableFacilities.Where(af => af.FacilityType == type)
.Union(RoomFacilities)
group fl by fl.Name into d
select new CheckableFacilityViewModel()
{
Name = d.Key,
IsChecked = (d.Count() > 1)
}
);
}
}
CheckableFacilityViewModel:
/* CheckableFacility has to be a viewmodel to serve the
ListViewItem in the UserControlHotelDescription (and other views) */
public class CheckableFacilityViewModel
{
public int Id { get; set; } /* I'm not sure if you use Id in your View */
public FacilityCategory ReporterFacilityCategory { get; set; }
public bool IsChecked { get; set; }
public string Name { get; set; }
}
CheckableFacilityView:
/* The ListViewItem has to be another View(usercontrol) 'CheckableFacilityView' */
<UserControl>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding Path=IsChecked}"/>
<TextBlock Text="{Binding Path=Name}" />
</StackPanel>
</UserControl>
