37

Goodday,

I want my combobox to select the first item in it. I am using C# and WPF. I read the data from a DataSet. To fill the combobox:

DataTable sitesTable = clGast.SelectAll().Tables[0];
cbGastid.ItemsSource = sitesTable.DefaultView;

Combo box XAML code:

<ComboBox 
   Name="cbGastid" 
   ItemsSource="{Binding}" 
   DisplayMemberPath="Description" 
   SelectedItem="{Binding Path=id}"
   IsSynchronizedWithCurrentItem="True" />

If I try:

cbGastid.SelectedIndex = 0; 

It doesn't work.

Brandon
  • 645
  • 5
  • 13
Roboneter
  • 867
  • 2
  • 13
  • 24

8 Answers8

56

Update your XAML with this:

<ComboBox 
        Name="cbGastid" 
        ItemsSource="{Binding}" 
        DisplayMemberPath="Description" 
        SelectedItem="{Binding Path=id}"
        IsSynchronizedWithCurrentItem="True"
        SelectedIndex="0" />  // Add me!
Brian
  • 5,069
  • 7
  • 37
  • 47
  • 8
    My `SelectedIndex="0"` still results in an empty combo, with item zero at the top when you drop it down. – ProfK Sep 21 '14 at 17:51
  • 19
    The property `IsSynchronizedWithCurrentItem="True"` worked for me – Ben Winding Dec 02 '15 at 03:59
  • 4
    THANK YOU! :) IsSynchronizedWithCurrentItem did the trick for me! – Ruaan Volschenk Feb 06 '17 at 07:37
  • 1
    Worked for me :) had to insert a dummy item into Index 0 on my data source but once I'd done that and made this change, all's good. – Ortund Jul 12 '17 at 07:06
  • 4
    IsSynchronizedWithCurrentItem="True" is enough and SelectedIndex="0" is not required. – Pabitra Dash Mar 31 '18 at 12:18
  • IsSynchronizedWithCurrentItem = "true" and SelectedIndex = 0 did show the right item text in the view, but did not update SelectedItem. So I just set my SelectedItem = myItems[0] when instanciating the Model (source). – tom2051 Jun 30 '22 at 13:31
8

Try this, instead of SelectedIndex

cbGastid.SelectedItem = sitesTable.DefaultView.[0][0]; // Assuming you have items here.

or set it in Xaml

<ComboBox 
        Name="cbGastid" 
        ItemsSource="{Binding}" 
        DisplayMemberPath="Description" 
        SelectedItem="{Binding Path=id}"
        IsSynchronizedWithCurrentItem="True"
        SelectedIndex="0" />
123 456 789 0
  • 10,565
  • 4
  • 43
  • 72
  • 1
    ** Error message: ** Error 1 'System.Data.DataView' does not contain a definition for 'FirstOrDefault' and no extension method 'FirstOrDefault' accepting a first argument of type 'System.Data.DataView' could be found (are you missing a using directive or an assembly reference?) C:\Users\Robin\Dropbox\School KW1C\Leerjaar 3\C#\Campingregistratie\Project\CampingRegistratie\CampingRegistratie\ReserveringenWindow3.xaml.cs 78 37 CampingRegistratie – Roboneter Dec 09 '13 at 20:36
2

It works for me if I add a SelectedIndex Property in my VM with the proper binding in the xaml. This is in addition to the ItemSource and the SelectedItem. This way SelectedIndex defaults to 0 and I got what I wanted.

    public List<string> ItemSource { get; } = new List<string> { "Item1", "Item2", "Item3" };
    public int TheSelectedIndex { get; set; }

    string _theSelectedItem = null;
    public string TheSelectedItem
    {
        get { return this._theSelectedItem; }
        set
        {
            this._theSelectedItem = value;
            this.RaisePropertyChangedEvent("TheSelectedItem"); 
        } 
    }

And the proper binding in the xaml;

    <ComboBox MaxHeight="25"  Margin="5,5,5,0" 
      ItemsSource="{Binding ItemSource}" 
      SelectedItem="{Binding TheSelectedItem, Mode=TwoWay}"
      SelectedIndex="{Binding TheSelectedIndex}" />
2

Update your XAML with this code :

<ComboBox 
   Name="cbGastid" 
   ItemsSource="{Binding}" 
   DisplayMemberPath="Description" 
   SelectedItem="{Binding Path=id, UpdateSourceTrigger=PropertyChanged, Mode=OneWayToSource}"
   IsSynchronizedWithCurrentItem="True" />

Hope it works :)

meghna
  • 21
  • 3
1

Try this,

remove from de C# code the following line:

cbGastid.ItemsSource = sitesTable.DefaultView; 

and add this:

cbGastid.DataContext = sitesTable.DefaultView
Appulus
  • 18,630
  • 11
  • 38
  • 46
Jose Luis
  • 37
  • 3
0

Try this..

    int selectedIndex = 0;
    cbGastid.SelectedItem = cbGastid.Items.GetItemAt(selectedIndex);

XAML Code:

    <ComboBox 
        Name="cbGastid" 
        ItemsSource="{Binding}" 
        DisplayMemberPath="Description" 
        SelectedItem="{Binding Path=id}"
        IsSynchronizedWithCurrentItem="True" />
Ravi Patel
  • 451
  • 1
  • 6
  • 17
0

Let me share my solution, that worked for me after several trials. Here is my combo box:

        <ComboBox   
                Name="fruitComboBox"
                ItemsSource="{Binding Fruits}"
                SelectedIndex="0"
                SelectedValue="{Binding ComboSelectedValue}"
                IsSynchronizedWithCurrentItem="True">

        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <i:InvokeCommandAction Command="{Binding displayFruitName}"         
                                       CommandParameter="{Binding SelectedValue, ElementName=fruitComboBox}"/>
            </i:EventTrigger>
            <i:EventTrigger EventName="Loaded">
                <i:InvokeCommandAction Command="{Binding displayFruitName}"         
                                       CommandParameter="{Binding SelectedValue, ElementName=fruitComboBox}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers> 
       
        </ComboBox>

In my case, I had to invoke a command every time a new item was selected in the comboBox or when the itemsource was being updated. But, the element at zero index was not getting selected when the item source was updated. So, what did I do? I added:

IsSynchronizedWithCurrentItem="True"

in the comboBox properties. It did the trick for me.

A little code from my ViewModel is below:

    /// item source for comboBox
    private List<string> fruits = new List<string>();
    public List<string> Fruits
    {
        get { return fruits; }
        set 
        {
            fruits = value;
            OnPropertyChanged();
            ComboSelectedValue = value[0];
        }
    }

    // property to which SelectedValue property of comboxBox is bound.
    private string comboselectedValue;
    public string ComboSelectedValue
    {
        get { return comboselectedValue; }
        set 
        { 
            comboselectedValue = value;
            OnPropertyChanged();
        }
    }

You can refer to this stackoverflow link and msdn link for further clarification regarding IsSynchronizedWithCurrentItem="True"

Hope it Helps! :)

Langdon
  • 27
  • 1
  • 6
Sabeen
  • 53
  • 5
0

This works for me... Given an Authors and Books table with a one-to-many relationship. The XAML Looks like this:

<ComboBox DisplayMemberPath="AuthorName" ItemsSource="{Binding Authors}" Name="ComboBoxAuthors"
              SelectedItem="{Binding SelectedAuthor}"
              IsSynchronizedWithCurrentItem="True" Grid.Row="0" Grid.Column="0"/>
<ComboBox DisplayMemberPath="BookTitle" ItemsSource="{Binding Books}" Name="ComboBoxBooks"
              SelectedItem="{Binding SelectedBook}"
              IsSynchronizedWithCurrentItem="True" Grid.Row="0" Grid.Column="1" />

Then my ViewModel looks like this:

enter public class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName = "")
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    BooksEntities ctx = new BooksEntities();
    List<Author> _authors;
    List<Book> _books;
    Author _selectedAuthor;
    Book _selectedBook;


    public MainViewModel()
    {
        FillAuthors();
    }

    public List<Author> Authors
    {
        get { return _authors; }
        set
        {
            _authors = value;
            NotifyPropertyChanged();
            if (_authors.Count > 0) SelectedAuthor = _authors[0]; // <--- DO THIS
        }
    }

    public Author SelectedAuthor
    {
        get { return _selectedAuthor; }
        set
        {
            _selectedAuthor = value;
            FillBooks();
            NotifyPropertyChanged();
        }
    }

    public List<Book> Books
    {
        get { return _books; }
        set
        {
            _books = value;
            NotifyPropertyChanged();
            if (_books.Count > 0) SelectedBook = _books[0]; // <--- DO THIS
        }
    }

    public Book SelectedBook
    {
        get { return _selectedBook; }
        set
        {
            _selectedBook = value;
            NotifyPropertyChanged();
        }
    }

    #region Private Functions

    private void FillAuthors()
    {
        var q = (from a in ctx.Authors select a).ToList();
        this.Authors = q;
    }

    private void FillBooks()
    {
        Author author = this.SelectedAuthor;

        var q = (from b in ctx.Books
                 orderby b.BookTitle
                 where b.AuthorId == author.Id
                 select b).ToList();
        this.Books = q;
    }

    #endregion
}

Take a look at the Authors and Books properties of the ViewModel class. Once they are set, the usual PropertyChanged event is raised and the SelectedAuthor / SelectedBook is set to the first item.

Hope this helps.

James
  • 31
  • 4