locked
How to set a member of a list as the initial selected item in a ComboBox bound to the list. RRS feed

  • Question

  • In an earlier post found here (http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/73eb8f23-e6be-4e61-aad3-e82bbf71101b), the question of how to bind a ComboBox to a filtered enumeration list was answered.

    Now I need to be able to select one of the list members as the initial selected item for the ComboBox.  The trivial solution of making the first item in the list be the desired initial selection will not work because the list needs to be displayed in the ComboBox in a particular order, like alphabetical or some other traditional ordering.  For example, the list may contain the members { V, mV, uV, nV } and the desired initial selection needs to be uV.

    For my application, the ComboBox that needs to have a particular initial list member displayed is at the end of a cascading filtering scheme, similar to the example provided in the post mentioned above.  In that posting we have the three enum lists Kingdom, Variety and Animal, which are bound to ComboBoxes through ObservableCollections.  In that example, the Animal displayed initially when the Kingdom is Land and the Variety is Dog would display Beagle as the selected item in the ComboBox.  But what if I want Poodle to be the initial selected item, without changing the order of the enum members?

    Is there a way to specify what member of the list is the initial selected item in the bound ComboBox?

    Thanks, Dave

     


    Dave R&D SW Engineer Agilent Technologies
    Wednesday, November 2, 2011 9:22 PM

Answers

  • Hi Dave,

    To make the sorting work, we can change the sorting path to empty in the code sample you provided. Because we are sorting on the AnimalEnum, it dosn't have a SelectedAnimal property.

    The default selected item isn't always the first item. The SelectedValue binding on the combobox and the sorting will affects the result. I was testing on the sample in your previous thread which doesn't have such problem. It turns out not a good solution in the end.

    Please check out the code in this sample. https://skydrive.live.com/#!/?cid=14362542b2fd72f8&sc=documents&uc=1&id=14362542B2FD72F8%21216.

    It basically uses the SelectedValue/SelectedItem to set the default item. To make this work with multiple levels, we add a new property to XYZInfo classes. And sorting is no longer needed in this approach.

    If you still have any questions or concerns about this issue, please feel free to let me know.

    Best regards,


    Min Zhu [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.

    • Marked as answer by Min Zhu Thursday, November 17, 2011 1:29 AM
    Thursday, November 10, 2011 3:34 AM

All replies

  • Hi Dave,

    The way I handle this is to bind the ComboBox.SelectedItem to a property on my view model, or same place as the ObservableCollection. Since this binding will be two-way, you can set the initial selection in your view model code and also have immediate access to the object that is selected. 

    If you do this, be sure to implement INotifyPropertyChanged and trigger the PropertyChanged event with the name of your SelectedItem property to get proper binding updates.

    Wednesday, November 2, 2011 11:52 PM
  • Hi Dave,

    If you want to set a default animal for each Variety, I think you can just change their orders in the collection.

    The first item in the collection will always be the default selected item. But we can re-sort the collection on the UI based on different rules.


    The following is a simple sample.

    Add the following code to the UserControl.

    var cvsDetector = this.FindResource("DetectorModeCollectionKey") as CollectionViewSource;
                cvsDetector.SortDescriptions.Add(new SortDescription("DetectionModeSelector", ListSortDirection.Ascending));
    


    Change the corresponding code to the following for GraphMeasSettings.SetupUnitsSelection method.

    ObservableCollection<DetectionModeInfo> FalseDetModes = new ObservableCollection<DetectionModeInfo>() { detModeEFalse, detModeATrue, detModeBFalse, detModeCFalse, detModeDFalse, detModeFFalse };
    

    Now if you select Other in the first combobox, you will see E initially selected in the second combobox. Open the dropdown of the second combobox and you will see the items are still sorted by their enum values.

    Best regards,


    Min Zhu [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.

    Thursday, November 3, 2011 2:08 AM
  • Min,

    Thanks for the reply.  The main problem with the proposed solution is that the ordering of the collection is limited to sorting either ascending or decending.  In my situation this type of ordering is not sufficient.  If my collection is initially ordered with the desirable default item listed first and then this type sorting is applied, it will not result in the desired displayed order.

    For example, let's say the enum members I want displayed are: enum Units {S, mS, uS, nS, V, mV, uV, nV}.  They are placed in the filtering collection in the following order to make the uV member be the default:

    ObservableCollection<Units> unitsVolts = new ObservableCollection<Units>() { Units.uV, Units.V, Units.mV, Units.nV };

    Now if they are simply sorted prior to being displayed in the drop down list, they will appear in one of the following alphabetical  orders: mV, nV, uV, V  or  V, uV, nV, mV.  Neither of these is the desired ordering: V, mV, uV, nV.

    Is there a way to specify a custom sort method for the CollectionViewSource resource?

    Thanks, Dave

     


    Dave R&D SW Engineer Agilent Technologies
    Thursday, November 3, 2011 4:46 PM
  • Hi Dave,

    The Enum will be sorted by their values not their names. So, in the previous code, "V, mV, uV, nV" will be in the exact order you want.

    And you can easily change their values to change their orders. For example,

        public enum DetectionModes
        {
            A=2, B=1, C=0, D=3, E=4, F=5
        }
    

    The above code will make the second combobox to show "C,B,A,D,E,F" for the previous sample.

     

    Anyway, you can also apply custom sorting as long as the collection type you use implements IList. ObservableCollection implements IList so we can apply custom sorting in this code.

                var cvsDetector = this.FindResource("DetectorModeCollectionKey") as CollectionViewSource;
                ListCollectionView viewDetector = cvsDetector.View as ListCollectionView;
                viewDetector.CustomSort = new DetectorComparer();
    
        public class DetectorComparer : System.Collections.IComparer
        {
            public int Compare(object x, object y)
            {
                throw new NotImplementedException();
            }
        }
    

     

    Best regards,


    Min Zhu [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.

    Friday, November 4, 2011 6:37 AM
  • Min,

    Using the standard (not custom) SortDecsription the solution described above is not working.  The enumeration has been defined in the desired display order (V, mV, uV, nV), placed in the collection with the desired default unit listed first (uV, V, mV, nV), and a SortDescription applied to the CollectionViewSource.  But what happens is the default unit may in fact show as the selected unit, but when the ComboBox is dropped down, the list is jumbled (not in either the defined order or the collection order.)

    Dave


    Dave R&D SW Engineer Agilent Technologies
    Tuesday, November 8, 2011 12:21 AM
  • Min,

    One other quick question.  In your first reply you said to "Add the following code to the UserControl."  I assumed you meant in the user control loaded event handler.  Is this correct?

    Thanks, Dave


    Dave R&D SW Engineer Agilent Technologies
    Tuesday, November 8, 2011 12:40 AM
  • Not sure if this suits your needs, but you could do something like this too...

     

        <StackPanel>
            <ComboBox ItemsSource="{Binding BirdList}" SelectedValue="{Binding BirdList.SelectedValue}"></ComboBox>
        </StackPanel>
    


    public partial class MainWindow : Window
        {
            public BirdList BirdList { get; set; }
    
            public MainWindow()
            {
                InitializeComponent();
    
                BirdList = new BirdList();
    
                this.DataContext = this;
            }
        }
    
        public class BirdList : EnumList<Animals>
        {
            public BirdList()
            {
                this.Add(Animals.Hawk);  // Define initial order
                this.Add(Animals.Crow);            
    
                SelectedValue = Animals.Hawk; // Define initial value
    
                this.Sort(new BirdList.BirdComparer1());  // Sort when/how desired
            }
    
            public class BirdComparer1 : IComparer<Enum>
            {
                public int Compare(Enum x, Enum y)
                {
                    return x.ToString().CompareTo(y.ToString());
                }
            }
        }
    
        public enum Animals
        {
            Crow,
            Hawk,
            Beagle,
            Poodle,
            Siamese,
            Tabby
        }
    
        public class EnumList<T> : List<Enum>
        {
            public Enum SelectedValue { get; set; }
        }
    


    Warm regards,

    Matt

    Tuesday, November 8, 2011 1:55 AM
  • Hi Dave,

    -->I assumed you meant in the user control loaded event handler.  Is this correct?

    Yeah, Loaded event is fine.

    -->Using the standard (not custom) SortDecsription the solution described above is not working.

    I tried the above code with your previous sample, and it works as expected on my side.

    I suggest you to check the following:

    It's the Enum's value that matter, have you tried explicitly setting the Enum values as below?

        public enum DetectionModes
        {
            A=0 B=1, C=2, D=3, E=4, F=5
        }
    


    Also, make sure the property path in SortDescription is correct.

    new SortDescription("DetectionModeSelector", ListSortDirection.Ascending)<br/>
    

    And Matt's suggestion is a very good solution in general. I didn't suggest that since you have multiple combobox so you will need to manually update the selected item when a parent combobox's selection changes.

    If it still cannot work, let me know and I will upload a demo. Or you can also share a demo project at SkyDrive https://skydrive.live.com/ so that we can see the problem more clearly.

    Best regards,


    Min Zhu [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.


    • Edited by Min Zhu Tuesday, November 8, 2011 2:31 AM
    Tuesday, November 8, 2011 2:29 AM
  • Min,

    I just copied an example solution to the skydrive location:

    https://skydrive.live.com/#!/?cid=cab2070bef48e29d&permissionsChanged=1&id=CAB2070BEF48E29D%21114!cid=CAB2070BEF48E29D&id=CAB2070BEF48E29D%21114

    The solution does the enum filtering correctly, but does not handle the default selection or sorting correctly.

    Thanks, Dave


    Dave R&D SW Engineer Agilent Technologies
    Tuesday, November 8, 2011 9:35 PM
  • Hi Dave,

    Just a quick note to let you know I have looked at your sample.

    Sorting doesn't work because the path is not correct.

    The default selected item doesn't work because it only works under certain conditions and doesn't seem to be a good solution. My approach doesn't seems to be reliable.

    Don't have enough time to post the details. I have an updated version that works and I will post it with the detailed explaination tomorrow.

    Best regards,


    Min Zhu [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.

    Wednesday, November 9, 2011 9:57 AM
  • Hi Dave,

    To make the sorting work, we can change the sorting path to empty in the code sample you provided. Because we are sorting on the AnimalEnum, it dosn't have a SelectedAnimal property.

    The default selected item isn't always the first item. The SelectedValue binding on the combobox and the sorting will affects the result. I was testing on the sample in your previous thread which doesn't have such problem. It turns out not a good solution in the end.

    Please check out the code in this sample. https://skydrive.live.com/#!/?cid=14362542b2fd72f8&sc=documents&uc=1&id=14362542B2FD72F8%21216.

    It basically uses the SelectedValue/SelectedItem to set the default item. To make this work with multiple levels, we add a new property to XYZInfo classes. And sorting is no longer needed in this approach.

    If you still have any questions or concerns about this issue, please feel free to let me know.

    Best regards,


    Min Zhu [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.

    • Marked as answer by Min Zhu Thursday, November 17, 2011 1:29 AM
    Thursday, November 10, 2011 3:34 AM
  • Hi Dave,

    Just checking in to see if the information was helpful. Please let us know if you would like further assistance.

    Have a great day!


    Min Zhu [MSFT]
    MSDN Community Support | Feedback to us
    Monday, November 14, 2011 2:23 AM