My Master's Thesis Problems and solutions encountered…

17Jul/100

Combobox two-way binding in MVVM

Almost all applications have a need of retrieving data into a combobox, and do something depending on what the user choses from the combobox. This is also the case in my application, and luckily Silverlight 4 has a pretty good way of dealing with the situation.

In this post I will show how you can populate a textbox with a QuestionnaireID depending on which QuestionnaireName the user has chosen from the combobox. Obviously, this is just a proof of method, as the the retrieved QuestionnaireID has another purpose (in my case it will be passed to a child window, and be used to update the database with the changes the user wants to make to the questionnaire). But for now, I will just show how you can solve the task taking into consideration the MVVM design structure.

I can recommend looking into the blog post called Binding to Silverlight ComboBox and Using SelectedValue, SelectedValuePath and DisplayMemberPath, if any questions come up, as you can download the complete source code from there.

So, as with all my other posts, the prerequisite is that you have a Model project where the objects are defined and populated with data fromn the database, and a View where you have all your .xaml files, and the ViewModel, that binds the two together and calls the Webservice.

Step 1: Go to your Model, and add a FirePropertyChanged to each of the attributes of the object.

    [DataContract(Name = "AllQuestionnaires")]
    public class DropBox_Questionnaire : INotifyPropertyChanged
    {

        string _questionnaireName;
        [DataMember]
        public string QuestionnaireName
        {
            get { return _questionnaireName; }
            set { _questionnaireName = value;
            FirePropertyChanged("QuestionnaireName");

            }
        }

        int _questionnaireID;
        [DataMember]
        public int QuestionnaireID
        {
            get { return _questionnaireID; }
            set { _questionnaireID = value;
            FirePropertyChanged("QuestionnaireID");
            }
        }

//INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        protected void FirePropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

    }

So you have now prepared the attributes for the two-way binding.

Step 2: In your ViewModel, create a SelectedQuestionnaire property that will contain the QuestionnaireID of the questionnaire, that the user has chosen. I have added all code, including the property for the Combobox, and the WebService call.


//Combox
      private ObservableCollection<AllQuestionnaires> _questList;
        public ObservableCollection<AllQuestionnaires> QuestList
        {
            get { return _questList; }
            set
            {
                _questList = value;
                RaisePropertyChanged("QuestList");
            }
        }

//Selected value
  private int _selectedQuestionnaire;
        public int SelectedQuestionnaire
        {
            get { return _selectedQuestionnaire; }
            set
            {
                _selectedQuestionnaire = value;
                RaisePropertyChanged("SelectedQuestionnaire");

            }
        }

//Constructor, Calls webservice
   public Client_Questionnaire2_ViewModel()
        {
            int UID = 2;
            int pq_ID = 1; //temporary hadrcoding

            QMServiceReference.Service1Client WebService = new Service1Client();

            WebService.GetAllQuestionnairesCompleted += new EventHandler<GetAllQuestionnairesCompletedEventArgs>(WebService_GetAllQuestionnairesCompleted);
            WebService.GetAllQuestionnairesAsync(UID, pq_ID);
}
//sets QuestList Property, returns data from database
   void WebService_GetAllQuestionnairesCompleted(object sender, GetAllQuestionnairesCompletedEventArgs e)
        {
            QuestList = e.Result;
        }

Step 3: Define the combobox in your xaml page in the View, and notice the ItemSource (that binds to the object) and the SelectedValue, that binds to the string property SelectedQuestionnaire that will contain what the user chooses (hence the TwoWay binding). The DisplayMemberPath and SelectedValuePath define the object attributes that the combobox will show, and the value it will send to SelectedQuestionnaire, respectively.

<!-- The combobox -->
<ComboBox  x:Name="QuestonnaireTest"
         ItemsSource="{Binding Path=QuestList, Mode=OneWay}"  //QuestList, property from ViewModel
         SelectedValue="{Binding Path=SelectedQuestionnaire, Mode=TwoWay}" //SelectedQuestionnaire, property from ViewModel
         DisplayMemberPath="QuestionnaireName" //Attribute from Model
         SelectedValuePath="QuestionnaireID" //Attribute from Model

/>

<!-- The textblock, where the QuestionnaireID is inserted -->

<TextBlock Name="textBlock" Text="{Binding Path=SelectedQuestionnaire, Mode=OneWay}" />

Enjoy!

Comments (0) Trackbacks (0)

No comments yet.


Leave a comment



− 4 = two

No trackbacks yet.