locked
Twoway binding for the SelectedItem in combobox RRS feed

  • Question

  • Hi,

    I have a combobox for which I have set the `
    ItemsSource="{Binding Path=Employee.EmployeeCollection}"
    SelectedItem="{Binding Path=Employee.CurrentEmployee }"

    The Xaml has its DataContext set to Employee.
    The ItemSource for the ComboBox is set to the EmployeeCollection which is a observable collection declared in Employee class.
    The SeletedItem of the combobox is set to the  CurrentEmployee property of the employee class.

        public class Employee {
            private string currentEmployee = string.Empty;
            private readonly string DefaultEmployee = "Select a employee";
        
            /// <summary>
            /// Constructor for the Employee.
            /// </summary>
            public Employee() {
                EmployeeCollection = new ObservableCollection<string>();
                LoadAllEmployees();
                CurrentEmployee = DefaultEmployee;
            }

            /// <summary>
            /// The active Employee selected in the Employee combobox.
            /// </summary>
            public string CurrentEmployee {
                get {
                    return currentEmployee;
                }
                set {
                    if (value != currentEmployee) {
                        currentEmployee = value;
                   }
                }
            }

            /// <summary>
            /// List of the Employee for which images are sent to print application.
            /// </summary>
            public ObservableCollection<string> EmployeeCollection {
                get;
                set;
            }

           private void LoadAllEmployees() {   
              EmployeeCollection.Add(DefaultEmployee);            
              EmployeeCollection.Add(“Employee1”);
              EmployeeCollection.Add(“Employee2”);
              EmployeeCollection.Add(“Employee3”);
              EmployeeCollection.Add(“Employee4”);
              EmployeeCollection.Add(“Employee5”);
              EmployeeCollection.Add(“Employee6”);
              EmployeeCollection.Add(“Employee7”);
            }          

        }


    The combobox is able to display all the  values from the EmployeeCollection.

    1.The problem I am facing is how to establish the two way binding for the selected item in combobox.
    That is when the selected item is changed in the combobox,the CurrentEmployee property should be updated and if there is change in the
    CurrentEmployee property on the Employee class,the selected item should reflect the change.

    2.The first time when the application comes up I want to set the CurrentEmployee to DefaultEmployee (“Select a employee”).

    Regards

    Vinutha

    Saturday, September 3, 2011 6:05 PM

Answers

  • Hello,

    To update the view when the CurrentEmployee property changes, the Employee class must implement INotifyPropertyChange:

    public class Employee:INotifyPropertyChanged
        {
            private string currentEmployee = string.Empty;
            private readonly string DefaultEmployee = "Select a employee";
    
            /// <summary>
            /// Constructor for the Employee.
            /// </summary>
            public Employee()
            {
                EmployeeCollection = new ObservableCollection<string>();
                LoadAllEmployees();
                CurrentEmployee = DefaultEmployee;
            }
    
            /// <summary>
            /// The active Employee selected in the Employee combobox.
            /// </summary>
            public string CurrentEmployee
            {
                get
                {
                    return currentEmployee;
                }
                set
                {
                    if (value != currentEmployee)
                    {
                        currentEmployee = value;
                        NotifyOfPropertyChange("CurrentEmployee");
                    }
                }
            }
    
            /// <summary>
            /// List of the Employee for which images are sent to print application.
            /// </summary>
            public ObservableCollection<string> EmployeeCollection
            {
                get;
                set;
            }
    
            private void LoadAllEmployees()
            {
                EmployeeCollection.Add(DefaultEmployee);
                EmployeeCollection.Add("Employee1");
                EmployeeCollection.Add("Employee2");
                EmployeeCollection.Add("Employee3");
                EmployeeCollection.Add("Employee4");
                EmployeeCollection.Add("Employee5");
                EmployeeCollection.Add("Employee6");
                EmployeeCollection.Add("Employee7");
            }
    
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void NotifyOfPropertyChange(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
    
            #endregion
        }
    

    Note that the PropertyChanged event is raised each time the CurrentEmployee property is updated.

    Good Luck.

     

    • Proposed as answer by Sheldon _Xiao Tuesday, September 6, 2011 6:24 AM
    • Marked as answer by Sheldon _Xiao Tuesday, September 13, 2011 6:15 AM
    Saturday, September 3, 2011 6:38 PM
  •  Hi,

    I am raising PropertyChanged event when the CurrentEmployee property is set.Should i need to to subscribe for the propertychanged event in the

    combobox UI and set the SelectedItem there?

    I want to establish two way binding between the SelectedItem of the ComboBox and CurrentEmployee property

    How should i bind the SelectedItem of the combobox to the CurrentEmployee property of the Employee class?

     

    Regards

    Vinutha

    Hi Vinutha,

    you do not need to subscribe. Everything should work fine with INotifyPropertyChanged automatically. Do you still have problems?


    "It's time to kick ass and chew bubble gum... and I'm all outta gum." - Duke Nukem
    • Proposed as answer by Sheldon _Xiao Tuesday, September 6, 2011 6:24 AM
    • Marked as answer by Sheldon _Xiao Tuesday, September 13, 2011 6:15 AM
    Sunday, September 4, 2011 11:57 AM
  • Hi Vinutha,

    U can achieve this very easily. U can either make ur "CurrentEmployee" property a "DependencyProperty" or u can implement "INotifyPropertyChanged" interface for ur "CurrentEmployee" property.

    Please see the code snippet below for the same.

    DependencyProperty example:
    
    public class Employee 
    {
            private readonly string DefaultEmployee = "Select a employee";
     	public static readonly DependencyProperty CurrentEmployeeProperty =
                DependencyProperty.Register("CurrentEmployee", typeof(String),
                typeof(IPBox), null);
    
            /// <summary>
            /// Gets or sets the CurrentEmployee 
            /// </summary>
            public String CurrentEmployee
            {
                get
                {
                    return (String)GetValue(CurrentEmployeeProperty);
                }
                set 
                { 
                    SetValue(CurrentEmployeeProperty, value);
                }
            }    
            /// <summary>
            /// Constructor for the Employee. 
            /// </summary>
            public Employee() {
                EmployeeCollection = new ObservableCollection<string>();
                LoadAllEmployees();
                CurrentEmployee = DefaultEmployee;
            }
    
            /// <summary>
            /// List of the Employee for which images are sent to print application.
            /// </summary>
            public ObservableCollection<string> EmployeeCollection {
                get;
                set;
            }
    
           private void LoadAllEmployees() {    
              EmployeeCollection.Add(DefaultEmployee);             
              EmployeeCollection.Add(“Employee1”);
              EmployeeCollection.Add(“Employee2”);
              EmployeeCollection.Add(“Employee3”);
              EmployeeCollection.Add(“Employee4”);
              EmployeeCollection.Add(“Employee5”);
              EmployeeCollection.Add(“Employee6”);
              EmployeeCollection.Add(“Employee7”);
            }          
    
        }
    
    INotifyPropertyChanged Interface Example:
    
    public class Employee : INotifyPropertyChanged
    {
    	public event PropertyChangedEventHandler PropertyChanged;
            private string currentEmployee = string.Empty;
            private readonly string DefaultEmployee = "Select a employee";
         
            /// <summary>
            /// Constructor for the Employee. 
            /// </summary>
            public Employee() {
                EmployeeCollection = new ObservableCollection<string>();
                LoadAllEmployees();
                CurrentEmployee = DefaultEmployee;
            }
    
            /// <summary>
            /// The active Employee selected in the Employee combobox.
            /// </summary>
            public string CurrentEmployee {
                get { 
                    return currentEmployee;
                }
                set {
                    if (value != currentEmployee) {
                        currentEmployee = value;
    		    this.OnPropertyChanged("CurrentEmployee");
                   }
                }
            }
    
            /// <summary>
            /// List of the Employee for which images are sent to print application.
            /// </summary>
            public ObservableCollection<string> EmployeeCollection {
                get;
                set;
            }
    
           private void LoadAllEmployees() {    
              EmployeeCollection.Add(DefaultEmployee);             
              EmployeeCollection.Add(“Employee1”);
              EmployeeCollection.Add(“Employee2”);
              EmployeeCollection.Add(“Employee3”);
              EmployeeCollection.Add(“Employee4”);
              EmployeeCollection.Add(“Employee5”);
              EmployeeCollection.Add(“Employee6”);
              EmployeeCollection.Add(“Employee7”);
            }      
    
    	protected virtual void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }    
    
        }

    DependencyProperty internally implements INotifyChanged interface thus updating the UI Element upon updating the value in the backend property.

    If ur property isn't DependencyProperty then u will have to implement the INotifyPropertyChanged interface in order to update the UI Element upon updating the value in the backend property.

    For more information on DependencyProperty and INotifyPropertyChanged interface please see the links below

    http://msdn.microsoft.com/en-us/library/ms752914.aspx

    http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.aspx

    http://blogs.microsoft.co.il/blogs/dorony/archive/2007/08/31/WPF-Binding_2C00_-INotifyPropertyChanged-and-Linq.aspx

    Please mark it as an answer if it resolves ur query.


    Regards, Parth Shah
    • Proposed as answer by parth.shah Saturday, September 3, 2011 6:46 PM
    • Marked as answer by Sheldon _Xiao Tuesday, September 13, 2011 6:15 AM
    Saturday, September 3, 2011 6:46 PM

All replies

  • Hello,

    To update the view when the CurrentEmployee property changes, the Employee class must implement INotifyPropertyChange:

    public class Employee:INotifyPropertyChanged
        {
            private string currentEmployee = string.Empty;
            private readonly string DefaultEmployee = "Select a employee";
    
            /// <summary>
            /// Constructor for the Employee.
            /// </summary>
            public Employee()
            {
                EmployeeCollection = new ObservableCollection<string>();
                LoadAllEmployees();
                CurrentEmployee = DefaultEmployee;
            }
    
            /// <summary>
            /// The active Employee selected in the Employee combobox.
            /// </summary>
            public string CurrentEmployee
            {
                get
                {
                    return currentEmployee;
                }
                set
                {
                    if (value != currentEmployee)
                    {
                        currentEmployee = value;
                        NotifyOfPropertyChange("CurrentEmployee");
                    }
                }
            }
    
            /// <summary>
            /// List of the Employee for which images are sent to print application.
            /// </summary>
            public ObservableCollection<string> EmployeeCollection
            {
                get;
                set;
            }
    
            private void LoadAllEmployees()
            {
                EmployeeCollection.Add(DefaultEmployee);
                EmployeeCollection.Add("Employee1");
                EmployeeCollection.Add("Employee2");
                EmployeeCollection.Add("Employee3");
                EmployeeCollection.Add("Employee4");
                EmployeeCollection.Add("Employee5");
                EmployeeCollection.Add("Employee6");
                EmployeeCollection.Add("Employee7");
            }
    
    
            #region INotifyPropertyChanged Members
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            private void NotifyOfPropertyChange(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
    
            #endregion
        }
    

    Note that the PropertyChanged event is raised each time the CurrentEmployee property is updated.

    Good Luck.

     

    • Proposed as answer by Sheldon _Xiao Tuesday, September 6, 2011 6:24 AM
    • Marked as answer by Sheldon _Xiao Tuesday, September 13, 2011 6:15 AM
    Saturday, September 3, 2011 6:38 PM
  • Hi Vinutha,

    U can achieve this very easily. U can either make ur "CurrentEmployee" property a "DependencyProperty" or u can implement "INotifyPropertyChanged" interface for ur "CurrentEmployee" property.

    Please see the code snippet below for the same.

    DependencyProperty example:
    
    public class Employee 
    {
            private readonly string DefaultEmployee = "Select a employee";
     	public static readonly DependencyProperty CurrentEmployeeProperty =
                DependencyProperty.Register("CurrentEmployee", typeof(String),
                typeof(IPBox), null);
    
            /// <summary>
            /// Gets or sets the CurrentEmployee 
            /// </summary>
            public String CurrentEmployee
            {
                get
                {
                    return (String)GetValue(CurrentEmployeeProperty);
                }
                set 
                { 
                    SetValue(CurrentEmployeeProperty, value);
                }
            }    
            /// <summary>
            /// Constructor for the Employee. 
            /// </summary>
            public Employee() {
                EmployeeCollection = new ObservableCollection<string>();
                LoadAllEmployees();
                CurrentEmployee = DefaultEmployee;
            }
    
            /// <summary>
            /// List of the Employee for which images are sent to print application.
            /// </summary>
            public ObservableCollection<string> EmployeeCollection {
                get;
                set;
            }
    
           private void LoadAllEmployees() {    
              EmployeeCollection.Add(DefaultEmployee);             
              EmployeeCollection.Add(“Employee1”);
              EmployeeCollection.Add(“Employee2”);
              EmployeeCollection.Add(“Employee3”);
              EmployeeCollection.Add(“Employee4”);
              EmployeeCollection.Add(“Employee5”);
              EmployeeCollection.Add(“Employee6”);
              EmployeeCollection.Add(“Employee7”);
            }          
    
        }
    
    INotifyPropertyChanged Interface Example:
    
    public class Employee : INotifyPropertyChanged
    {
    	public event PropertyChangedEventHandler PropertyChanged;
            private string currentEmployee = string.Empty;
            private readonly string DefaultEmployee = "Select a employee";
         
            /// <summary>
            /// Constructor for the Employee. 
            /// </summary>
            public Employee() {
                EmployeeCollection = new ObservableCollection<string>();
                LoadAllEmployees();
                CurrentEmployee = DefaultEmployee;
            }
    
            /// <summary>
            /// The active Employee selected in the Employee combobox.
            /// </summary>
            public string CurrentEmployee {
                get { 
                    return currentEmployee;
                }
                set {
                    if (value != currentEmployee) {
                        currentEmployee = value;
    		    this.OnPropertyChanged("CurrentEmployee");
                   }
                }
            }
    
            /// <summary>
            /// List of the Employee for which images are sent to print application.
            /// </summary>
            public ObservableCollection<string> EmployeeCollection {
                get;
                set;
            }
    
           private void LoadAllEmployees() {    
              EmployeeCollection.Add(DefaultEmployee);             
              EmployeeCollection.Add(“Employee1”);
              EmployeeCollection.Add(“Employee2”);
              EmployeeCollection.Add(“Employee3”);
              EmployeeCollection.Add(“Employee4”);
              EmployeeCollection.Add(“Employee5”);
              EmployeeCollection.Add(“Employee6”);
              EmployeeCollection.Add(“Employee7”);
            }      
    
    	protected virtual void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }    
    
        }

    DependencyProperty internally implements INotifyChanged interface thus updating the UI Element upon updating the value in the backend property.

    If ur property isn't DependencyProperty then u will have to implement the INotifyPropertyChanged interface in order to update the UI Element upon updating the value in the backend property.

    For more information on DependencyProperty and INotifyPropertyChanged interface please see the links below

    http://msdn.microsoft.com/en-us/library/ms752914.aspx

    http://msdn.microsoft.com/en-us/library/system.windows.dependencyproperty.aspx

    http://blogs.microsoft.co.il/blogs/dorony/archive/2007/08/31/WPF-Binding_2C00_-INotifyPropertyChanged-and-Linq.aspx

    Please mark it as an answer if it resolves ur query.


    Regards, Parth Shah
    • Proposed as answer by parth.shah Saturday, September 3, 2011 6:46 PM
    • Marked as answer by Sheldon _Xiao Tuesday, September 13, 2011 6:15 AM
    Saturday, September 3, 2011 6:46 PM
  •  Hi,

    I am raising PropertyChanged event when the CurrentEmployee property is set.Should i need to to subscribe for the propertychanged event in the

    combobox UI and set the SelectedItem there?

    I want to establish two way binding between the SelectedItem of the ComboBox and CurrentEmployee property

    How should i bind the SelectedItem of the combobox to the CurrentEmployee property of the Employee class?

     

    Regards

    Vinutha

    Sunday, September 4, 2011 9:49 AM
  •  Hi,

    I am raising PropertyChanged event when the CurrentEmployee property is set.Should i need to to subscribe for the propertychanged event in the

    combobox UI and set the SelectedItem there?

    I want to establish two way binding between the SelectedItem of the ComboBox and CurrentEmployee property

    How should i bind the SelectedItem of the combobox to the CurrentEmployee property of the Employee class?

     

    Regards

    Vinutha

    Hi Vinutha,

    you do not need to subscribe. Everything should work fine with INotifyPropertyChanged automatically. Do you still have problems?


    "It's time to kick ass and chew bubble gum... and I'm all outta gum." - Duke Nukem
    • Proposed as answer by Sheldon _Xiao Tuesday, September 6, 2011 6:24 AM
    • Marked as answer by Sheldon _Xiao Tuesday, September 13, 2011 6:15 AM
    Sunday, September 4, 2011 11:57 AM
  • Hi Vinutha,

    Please see the code snippet below for ur query.

    It works in two way mode i.e. changing the property from codebehind updates the UI and changing the UI value updates the property

    XAML:
    
    <Window x:Class="SandBox.Window14"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window14" Height="300" Width="300">
        <Grid>
            <ComboBox x:Name="cmb" ItemsSource="{Binding Path=EmployeeObject.EmployeeCollection}" 
    SelectedItem="{Binding Path=EmployeeObject.CurrentEmployee }" SelectionChanged="cmb_SelectionChanged"></ComboBox>
        </Grid>
    </Window>
    
    
    CodeBehind:
    
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;
    using System.ComponentModel;
    
    namespace SandBox
    {
        /// <summary>
        /// Interaction logic for Window14.xaml
        /// </summary>
        public partial class Window14 : Window
        {
            public Employee EmployeeObject { get; set; }
            public Window14()
            {
                InitializeComponent();
                EmployeeObject = new Employee();
                cmb.DataContext = this;
                EmployeeObject.CurrentEmployee = "Employee1";
            }
    
            private void cmb_SelectionChanged(object sender, SelectionChangedEventArgs e)
            {
    
            }
        }
    
        public class Employee : INotifyPropertyChanged
    {
    	public event PropertyChangedEventHandler PropertyChanged;
            private string currentEmployee = string.Empty;
            private readonly string DefaultEmployee = "Select a employee";
         
            /// <summary>
            /// Constructor for the Employee. 
            /// </summary>
            public Employee() {
                EmployeeCollection = new ObservableCollection<string>();
                LoadAllEmployees();
                CurrentEmployee = DefaultEmployee;
            }
    
            /// <summary>
            /// The active Employee selected in the Employee combobox.
            /// </summary>
            public string CurrentEmployee {
                get { 
                    return currentEmployee;
                }
                set {
                    if (value != currentEmployee) {
                        currentEmployee = value;
    		    this.OnPropertyChanged("CurrentEmployee");
                   }
                }
            }
    
            /// <summary>
            /// List of the Employee for which images are sent to print application.
            /// </summary>
            public ObservableCollection<string> EmployeeCollection {
                get;
                set;
            }
    
           private void LoadAllEmployees() {    
              EmployeeCollection.Add(DefaultEmployee);             
              EmployeeCollection.Add("Employee1");
              EmployeeCollection.Add("Employee2");
              EmployeeCollection.Add("Employee3");
              EmployeeCollection.Add("Employee4");
              EmployeeCollection.Add("Employee5");
              EmployeeCollection.Add("Employee6");
              EmployeeCollection.Add("Employee7");
            }      
    
    	protected virtual void OnPropertyChanged(string propertyName)
            {
                if (this.PropertyChanged != null)
                    this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }    
    
        }
    }
    
    Please mark it as an answer if it resolves ur query.

    Regards, Parth Shah
    • Proposed as answer by parth.shah Monday, September 5, 2011 12:19 PM
    Monday, September 5, 2011 12:19 PM
  • Hi Vinutha,

    Anu updates over this.

    Did u try this out. If u have any queries please let me know.

    If ur issue is resolved please close the post and mark it as an answer.


    Regards, Parth Shah
    Tuesday, September 6, 2011 6:59 AM
  • Hi Vinutha,

    Anu updates over this.

    If ur issue is resolved please close the post and mark it as an answer.


    Regards, Parth Shah
    Saturday, September 10, 2011 12:17 PM
  • Hi Vinutha,

    Anu updates over this.

    If ur issue is resolved please close the post and mark it as an answer.


    Regards, Parth Shah
    Monday, September 12, 2011 1:24 PM
  • I am marking your issue as "Answered", if you have new findings about your issue, please let me know.

     

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, September 13, 2011 6:16 AM