locked
Setting SelectedValue does't Update Combobox RRS feed

  • Question

  • Hi,

    Setting SelectedValue is not updating ComboBox....

    Here is Code:

    XAML:

      
    
      <ComboBox Name="cmbValue" ItemsSource="{Binding EnumEntries}"
    
    SelectedValuePath="Key"
    
         SelectedValue="{Binding Path=keyValue, UpdateSourceTrigger=PropertyChanged}">
    
       <ComboBox.ItemTemplate>
    
        <DataTemplate>
    
          <TextBlock Text="{Binding Path=Value}"/>
    
        </DataTemplate>
    
       </ComboBox.ItemTemplate>

    C#:

    private List<DictionaryEntry> enumEntries;
    
    
    
    public List<DictionaryEntry> EnumEntries
    
      {
    
       get { return enumEntries; }
    
       set { enumEntries = value; }
    
      }
    
    
    
    public Method1()
    
    {
    
    enumEntries = new List<DictionaryEntry>();
    
       enumEntries.Add(new DictionaryEntry(1, "None"));
    
       enumEntries.Add(new DictionaryEntry(2, "Two"));
    
       enumEntries.Add(new DictionaryEntry(3, "Three"));
    
       enumEntries.Add(new DictionaryEntry(4, "Four"));
    
       enumEntries.Add(new DictionaryEntry(5, "Five Six Seven Eight"));
    
       keyValue = "1";
    
    }
    
    
    
    
    
    


    After calling Method1() i am expecting ComboBox with "None" as selected... but its not happening....

    Am i missing something here...Please help me,....


    Friday, July 22, 2011 11:18 AM

Answers

  • Hello,

    As I stated before, you should change your List<DictionaryEntry> by an ObservableCollection<DictionaryEntry>.

     

    • Proposed as answer by Sheldon _Xiao Tuesday, August 2, 2011 6:55 AM
    • Marked as answer by Sheldon _Xiao Friday, August 5, 2011 6:12 AM
    Friday, July 22, 2011 2:10 PM
  • you could also use following
    <ComboBox 
     Name="cmbValue" ItemsSource="{Binding EnumEntries}" SelectedValuePath="Key"
     SelectedValue="{Binding Path=SelectedValue, UpdateSourceTrigger=PropertyChanged}">
     <ComboBox.ItemTemplate>
      <DataTemplate>
       <TextBlock Text="{Binding Path=Value}"/>
      </DataTemplate>
     </ComboBox.ItemTemplate>
    </ComboBox>
    


    and change the ViewModel class as so

     

    private object _selectedItem;
    public object SelectedItem 
    {
     get { return _selectedItem; }
     set
     {
      _selectedItem = value;
      OnPropertyChanged("SelectedItem");
     }
    }
    
    
    ...
    
    public void Method1()
    {
     List<DictionaryEntry> list = new List<DictionaryEntry>();
     list.Add(new DictionaryEntry(1, "None"));
     ...
    
     EnumEntries = new ObservableCollection<DictionaryEntry>(list);
     //SelectedItem = EnumEntries[0];
     SelectedItem = 1;
    }
    

     


    • Proposed as answer by Sheldon _Xiao Tuesday, August 2, 2011 6:54 AM
    • Marked as answer by Sheldon _Xiao Friday, August 5, 2011 6:12 AM
    Friday, July 22, 2011 2:10 PM

All replies

  • Hi,

    Yes you are missing some code. What I suggest is that while Binding of Selected Value use Mode : Two Way in XAML.

    e.g SelectedValue="{Binding Path=keyValue, UpdateSourceTrigger=PropertyChanged , Mode = TwoWay}">

    And one more thing is Set the DataContext of ur XAML window with your Entity and Derive your entity from INotifyProperty and Implement it.

    e.g   

      get

    {return;}

    set

    {

      NotifyPropertyCHanged(....)

    }

     

     

    I Have tried many times at my place and its working fine.

    Please try and if some problem occurs reply back.

     

    Regards,

    Robin Raina.

     

     



    Friday, July 22, 2011 11:30 AM
  • Thanks Robin. I tried your suggestion.. setting mode to TwoWay...

    SelectedValue="{Binding Path=keyValue, UpdateSourceTrigger=PropertyChanged , Mode = TwoWay}">

    But some how its not working out..

    Can u please share the working example, if you have... Thanks...

    Friday, July 22, 2011 11:36 AM
  • Hello,

     

    Sorry for jumping in. When you need to bind a list with a control you should use an ObservableCollection<>:

     

        public MainWindow()
        {
          InitializeComponent();
          this.DataContext = this;
        }
    
        private ObservableCollection<DictionaryEntry> enumEntries;
        private int keyValue;
    
        public ObservableCollection<DictionaryEntry> EnumEntries
        {
          get { return enumEntries; }
          set 
          { 
            enumEntries = value;
            NotifyOfPropertyChange("EnumEntries");
          }
        }
    
        public int KeyValue
        {
          get { return keyValue; }
          set 
          {
            keyValue = value;
            NotifyOfPropertyChange("KeyValue");
          }
        }
    
        public void Method1()
        {
          EnumEntries = new ObservableCollection<DictionaryEntry>();
          EnumEntries.Add(new DictionaryEntry(1, "None"));
          EnumEntries.Add(new DictionaryEntry(2, "Two"));
          EnumEntries.Add(new DictionaryEntry(3, "Three"));
          EnumEntries.Add(new DictionaryEntry(4, "Four"));
          EnumEntries.Add(new DictionaryEntry(5, "Five Six Seven Eight"));
          KeyValue = 1;
        }
    
        #region INotifyPropertyChanged Members
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        public void NotifyOfPropertyChange(string propertyName)
        {
          if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    
        #endregion
    
    This code works fine with your xaml.

    Good Luck.

     

    Friday, July 22, 2011 11:50 AM
  • I would agree with Robin, implementing a property changed notifier would be your best bet, especially if you're going MVVM or plan to implement other properties that will require change notification.  If that's not an option you could set your property in the change event of the combobox or get really elaborate and use a converter in your binding (bind to selected index) and convert from SelectedValue to SelectedIndex.  All would be acceptable solutions, the first being your best bet...I guess it depends on your requirements.

    Hope it helps,

    Aj


    If at first you don't succeed, skydiving is definitely not for you!
    Friday, July 22, 2011 11:53 AM
  • Hi,

    In you case you have kept

     keyValue = "1";

    Note as you have binded your itemsource with some collection of Strings,

    so selected Value should be string and its value should be one of the item from the collection.

    I can give one small example:

     

    Suppose I have one Entity

    Class A

    {

       Public string SelectedValue

    {

    get;

    set;

    }

    }

    Now you have your XAML.cs file.

    Set the DataContext with Entity and Bind it It will work.

    Friday, July 22, 2011 12:06 PM
  • Hi.... Apologies if i confused you guys..

    Here is my problem description:

    I have a  collection List<DictionaryEntry>. This list i have bound with Combobox using "ItemSource". Since Dictionary is "Key" and "Value" pair, I want Value to be displayed in the dropdown. This i have done using "DataTemplate". Now When user selects some item from the ComboBox, i want to retrieve "Key" Value rather than "DictionaryEntry" or "Value". This i have done using "SelectedValuePath" (Find XAML snippet below). And i have implemented INotifyPropertyChage and Set Mode to "TwoWay" to have "KEY" bound with "keyValue" property of .NET. Till here it works perferctly, means, When i select "Three" from i could see "keyValue" as "3".

    Now, When I set "keyValue" programatically to "4", I want to see ComboBox to show as "Four" selected.. Which is not happening...

    <ComboBox Name="cmbValue" ItemsSource="{Binding EnumEntries}"
    SelectedValuePath="Key"
       SelectedValue="{Binding Path=keyValue, UpdateSourceTrigger=PropertyChanged}">
      <ComboBox.ItemTemplate>
      <DataTemplate>
       <TextBlock Text="{Binding Path=Value}"/>
      </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>
    
    Friday, July 22, 2011 1:12 PM
  • Hi,

     

    with the following XAML

    <ComboBox 
      Name="cmbValue" ItemsSource="{Binding EnumEntries}" SelectedValuePath="Key"
      SelectedItem="{Binding Path=SelectedItem, UpdateSourceTrigger=PropertyChanged}">
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Path=Value}"/>
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>
    

    and this class as teh DataContext it works as desired

    public class ViewModel : INotifyPropertyChanged
    {
      private ObservableCollection<DictionaryEntry> enumEntries;
    
      public ViewModel()
      {
        Method1();
      }
    
      private DictionaryEntry _selectedItem;
      public DictionaryEntry SelectedItem 
      {
        get { return _selectedItem; }
        set
        {
          _selectedItem = value;
          OnPropertyChanged("SelectedItem");
        }
      }
    
      public ObservableCollection<DictionaryEntry> EnumEntries
      {
        get { return enumEntries; }
        set { enumEntries = value; }
      }
    
      public void Method1()
      {
        List<DictionaryEntry> list = new List<DictionaryEntry>();
        list.Add(new DictionaryEntry(1, "None"));
        list.Add(new DictionaryEntry(2, "Two"));
        list.Add(new DictionaryEntry(3, "Three"));
        list.Add(new DictionaryEntry(4, "Four"));
        list.Add(new DictionaryEntry(5, "Five Six Seven Eight"));
    
        EnumEntries = new ObservableCollection<DictionaryEntry>(list);
        SelectedItem = EnumEntries[0];
      }
      
      #region INotifyPropertyChanged Members
    
      public event PropertyChangedEventHandler PropertyChanged = delegate {};
    
      private void OnPropertyChanged(string propertyName)
      {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
    
      #endregion
    }
    

    Friday, July 22, 2011 1:59 PM
  • Hello,

    As I stated before, you should change your List<DictionaryEntry> by an ObservableCollection<DictionaryEntry>.

     

    • Proposed as answer by Sheldon _Xiao Tuesday, August 2, 2011 6:55 AM
    • Marked as answer by Sheldon _Xiao Friday, August 5, 2011 6:12 AM
    Friday, July 22, 2011 2:10 PM
  • you could also use following
    <ComboBox 
     Name="cmbValue" ItemsSource="{Binding EnumEntries}" SelectedValuePath="Key"
     SelectedValue="{Binding Path=SelectedValue, UpdateSourceTrigger=PropertyChanged}">
     <ComboBox.ItemTemplate>
      <DataTemplate>
       <TextBlock Text="{Binding Path=Value}"/>
      </DataTemplate>
     </ComboBox.ItemTemplate>
    </ComboBox>
    


    and change the ViewModel class as so

     

    private object _selectedItem;
    public object SelectedItem 
    {
     get { return _selectedItem; }
     set
     {
      _selectedItem = value;
      OnPropertyChanged("SelectedItem");
     }
    }
    
    
    ...
    
    public void Method1()
    {
     List<DictionaryEntry> list = new List<DictionaryEntry>();
     list.Add(new DictionaryEntry(1, "None"));
     ...
    
     EnumEntries = new ObservableCollection<DictionaryEntry>(list);
     //SelectedItem = EnumEntries[0];
     SelectedItem = 1;
    }
    

     


    • Proposed as answer by Sheldon _Xiao Tuesday, August 2, 2011 6:54 AM
    • Marked as answer by Sheldon _Xiao Friday, August 5, 2011 6:12 AM
    Friday, July 22, 2011 2:10 PM
  • Hi,

    actually the ObservableCollection should be used if the collection itself is changed during runtime, by adding /removing items. If the collection itself won't change, than the ObservableCollection is not needed.


    Friday, July 22, 2011 2:23 PM
  • Hi thisissuneel,

    How about your concern?


    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, August 2, 2011 6:54 AM