My Combobox Selected Value binding doesn't flow back in Two Way Data binding

714 views Asked by At

Im Using Simple MVVM Framework to create a simple Silverlight 4.0 LOB Application.

I have an Employee List View that shows List Of all Employees in and i have in my EmployeeListViewModel some properties As Follow:

    private Grade selectedGrade;
    public Grade SelectedGrade
    {
        get { return selectedGrade; }
        set
        {
            selectedGrade = value;
            NotifyPropertyChanged(m => m.SelectedGrade);
        }
    }

    private Religion selectedReligion;
    public Religion SelectedReligion
    {
        get { return selectedReligion; }
        set
        {
            selectedReligion = value;
            NotifyPropertyChanged(m => m.SelectedReligion);
        }
    }
    private ObservableCollection<Grade> grades;
    public ObservableCollection<Grade> Grades
    {
        get { return grades; }
        set
        {
            grades = value;
            NotifyPropertyChanged(m => m.Grades);
        }
    }

    private ObservableCollection<Religion> religions;
    public ObservableCollection<Religion> Religions
    {
        get { return religions; }
        set
        {
            religions = value;
            NotifyPropertyChanged(m => m.Religions);
        }
    }
    private ObservableCollection<Department> departments;
    public ObservableCollection<Department> Departments
    {
        get { return departments; }
        set
        {
            departments = value;
            NotifyPropertyChanged(m => m.Departments);
        }
    }
    private Employee selectedEmployee;
    public Employee SelectedEmployee
    {
        get { return selectedEmployee; }
        set
        {
            selectedEmployee = value;
            SetCanProperties();
            NotifyPropertyChanged(m => m.SelectedEmployee);
        }
    }
    private ObservableCollection<Employee> employees;   
    public ObservableCollection<Employee> Employees
    {
        get { return employees; }
        set
        {
            employees = value;
            NotifyPropertyChanged(m => m.Employees);
        }
    }
    private Department selectedDepartment;
    public Department SelectedDepartment
    {
        get { return selectedDepartment; }
        set
        {
            selectedDepartment = value;
            NotifyPropertyChanged(m => m.SelectedDepartment);
        }
    }

now in my view i have a button to edit selected employee in my Employee List that opens up a new Child Window with the EmployeeDetails to Edit

  EmployeeListViewModel viewModel;
    public EmployeeListView()
    {
        InitializeComponent();
        viewModel = (EmployeeListViewModel)DataContext;
    }

and here is the edit employee Method

 private void editItemButton_Click(object sender, RoutedEventArgs e)
    {
        // Exit if no product selected
        if (viewModel.SelectedEmployee == null) return;

        // Create a product detail model
       EmployeeDetailViewModel detailModel =
            new  EmployeeDetailViewModel(viewModel.SelectedEmployee);
        // set comboboxes !! 

       detailModel.Departments = viewModel.Departments;
       detailModel.Religions = viewModel.Religions;

       detailModel.Grades = viewModel.Grades;

        // Start editing
        detailModel.BeginEdit();

        // Show EmployeeDetail view
       EmployeeDetailView itemDetail = new  EmployeeDetailView(detailModel);
        itemDetail.Closed += (s, ea) =>
        {
            if (itemDetail.DialogResult == true)
            {
                // Confirm changes

                detailModel.EndEdit();
            }
            else
            {
                // Reject changes
                detailModel.CancelEdit();
            }
        };
        itemDetail.Show();
    }

now on my details Child View I have this Constractor

   public EmployeeDetailView(EmployeeDetailViewModel viewModel)
    {
        InitializeComponent();
        DataContext = viewModel;
    }

and here is my DetailsViewModel constractor

   public EmployeeDetailViewModel(Employee model)
    {
        base.Model = model;
    }
         private ObservableCollection<Religion> religions;
    public ObservableCollection<Religion> Religions
    {
        get { return religions; }
        set
        {
            religions = value;
            NotifyPropertyChanged(m => m.Religions);
        }
    }

    private ObservableCollection<Grade> grades;
    public ObservableCollection<Grade> Grades
    {
        get { return grades; }
        set
        {
            grades = value;
            NotifyPropertyChanged(m => m.Grades);
        }
    }
    private ObservableCollection<Department> departments;
    public ObservableCollection<Department> Departments
    {
        get { return departments; }
        set
        {
            departments = value;
            NotifyPropertyChanged(m => m.Departments);
        }
    }

after all this now comes the binding i have three comboboxes for Departments, Religions and Grades (Which are foreign keys in my employee table)

 <ComboBox  ItemsSource="{Binding Departments}" DisplayMemberPath="DepartmentName" SelectedValue="{Binding Model.Emp_Department, Mode=TwoWay}" SelectedValuePath="DepartmentId"/>
   <ComboBox  ItemsSource="{Binding Grades}" DisplayMemberPath="GradeName" SelectedValue="{Binding Model.Emp_Grade, Mode=TwoWay}" SelectedValuePath="GradeId"/>

and so on .. The problem is that only the Departments combo box is updating the source value when i change its value

and the other combo boxes don't .. even when the binding statement is exactly the same !!

so sorry for writing so much .. but can anyone help me with this ??

thanks a lot

2

There are 2 answers

2
ibebbs On

Unfortunately your MVVM separation is a little messed up as you are binding from the View directly to the underlying Model (meaning any business logic / validation in the ViewModel) is bypassed.

However, you seem to have everything in place so I would suggest the following:

Change your Xaml to this (note the change from SelectedValue to SelectedItem):

<ComboBox  ItemsSource="{Binding Departments}" DisplayMemberPath="DepartmentName" SelectedItem="{Binding SelectedDepartment, Mode=TwoWay}"/>
<ComboBox  ItemsSource="{Binding Grades}" DisplayMemberPath="GradeName" SelectedItem="{Binding SelectedGrade, Mode=TwoWay}"/>

Then within the setter of the SelectedDepartment/SelectedGrade properties, perform any required validation and then write the Id of the selected item to the properties in your (detail) model.

Hope it helps.

0
Emy On

well here is how i do my combos:

 <ComboBox ItemsSource="{Binding Path=ListPeople, UpdateSourceTrigger= PropertyChanged}" SelectedItem="{Binding Path=SelectedPerson, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayMemberPath="FirstName"/>

and in my viewmodel:

 private ObservableCollection<Person> listPeople = new ObservableCollection<Person>();

 public IEnumerable<Person> ListPeople
     {
         get { return this.listPeople; }
     }

 public Person SelectedPerson
     {
         get { return selectedPerson; }
         set
         {
             selectedPerson = value;
             if (selectedPerson != null)
             {
                 NextToPayID = selectedPerson.PersonID;
             }
             base.RaisePropertyChanged("SelectedPerson");
         }
     }

see if you can use that to help!