如何为具有集合的模型创建viewmodel

时间:2010-07-08 08:33:45

标签: c# wpf mvvm

我有一个班级:

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


    }

1 个答案:

答案 0 :(得分:5)

您是否要为每个模型创建一个ViewModel?我耽心。

应为每个视图创建ViewModel,该视图具有View的元素可以绑定到的所有属性。

如果属性是来自数据库的数据,则它将作为属性存在于模型中,并且可以由viewmodel使用,而无需创建任何成员。否则你的viewmodel与模型无关。

创建模型后,请将其放在一边。然后创建视图。检查绑定所需的数据。根据视图的要求在ViewModel中创建任意数量的属性。大多数数据将取决于模型(可能是不同的模型)或模型中数据的推导。因此,创建所需的模型实例,以便可以通过ViewModel获取和设置它们的属性。

如果您仍然无法获得清晰的图片,请将您的观点发送给我。我将创建一个示例视图模型。

<强>更新

HotelDescriptionModelView:

/* 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>