tags:

views:

100

answers:

1

I have a class :

public class Car
{        
    public string Name { get; set; }
    public int Age { get; set; }
    public Wheel[] Wheels {get;set;}       
}

Collections of wheels can be changed

Every properties of Car will be showing at the same control

I want to see how make a ViewModel for this class.

Had I good understood conception of 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();
}
}
}

I paste code of my application where I have problem with this MVVM(I'm not sure of good implementation, And removing Facility doesn't work. Could you help me rebuild this code?

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


    }
+4  A: 

Are you going to create a ViewModel for each of your model? I'm afraid.

ViewModel should be created for each view which would have all the properties to which the View's elements could be bound to.

If the property is a data from your db, it would be in the model as a property and could be used by the viewmodel without creating any member. Else your viewmodel has nothing to do with the model.

Once you've created the Model, keep it aside. Then create the view. Check what are the data required for the binding. Create as many properties in the ViewModel as required by the view. Most of the data would be dependent on the Model (may be different models) or the derivation of the data in the model. Hence create the required model instances so that their properties could be get and set through ViewModel.

If you still couldn't get a clear picture, send me your view. I will create a sample viewmodel out of it.

Update

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>
Veer
I added part of my application
I agree, creation of ViewModel should depend on the view rather then model.
akjoshi
@phenevo: It seems you're doing things wrongly. Check my edit. That could start you up. However send me your design/requirement. I'll tell you how to do things and you could proceed.
Veer
I have description of Hotel. Description has list of Facilities, coordinates, opinion, and everything what is related with hotel. User can add new description, and edit old. At main window user has a few grids where he see list of facilities(I keep theirs in xml). User at this lists can mark facilities(eg. hotel has TV in room so he marks TV at list). Depending of FacilityType(Room, Object (eg.security, carpark) I puts facility in matching list (so I have list of room facility, objectFacility etc). When user click save I save HotelDescription in xml.
@Veer Could you show me how to use CheckableFacilityViewModel ? And Megathanks for job You do for me :)
@phenevo: It's just an alias I've given for your CheckableFacility to preserve the consistency of the naming convention. Check my edit. It is used in the `ObservableCollection` and `GetCheckableFacilities`.
Veer