Click here to Skip to main content
15,886,067 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a Session table. Within the Session table I have a field - SessionTypeID - that references the SessionType table (foreign key). I have a combobox that I have created with SessionTypeName entries from the SessionType file. When a Session is selected I want to match the SessionTypeID from the Session file, with the entries in the SessionType combobox, and make that the selected (default) index. I assumed I would iterate through the combobox items and find the matching entry, but it's proving more difficult than I anticipated. I'm using WPF, C# and .NET 4.6 All the examples I've found don't seem to work with 4.6.

For example:

C#
for (int i = 0; i < comboBoxSessionDataSessionType.Items.Count; ++i)
{
    MessageBox.Show(comboBoxSessionDataSessionType.Items[i].ToString());
}

shows the following: 'Systems.Windows.Controls.ComboBoxItem: 120 Film'
'120 Film' is the value I'm looking for.

Any ideas on how to accomplish this?

Here is the code for getting the Session table data:

C#
string sql = @"SELECT * FROM Session WHERE SessionID = '" + id + "'";
           //  MessageBox.Show(sql);
           SQLiteCommand com = new SQLiteCommand(sql, conn);
           System.Data.DataSet ds = new System.Data.DataSet();
           SQLiteDataAdapter ad = new SQLiteDataAdapter(sql, conn);
           ad.Fill(ds);
           GridSessionData.DataContext = ds.Tables[0].DefaultView;


Here is the button XAML code:

XML
<combobox x:name="comboBoxSessionDataSessionType" grid.column="1" grid.row="2" style="{DynamicResource ComboboxData}" itemssource="{Binding Path=SessionTypeID, Mode=TwoWay}" datacontext="{Binding SessionTypeName}" selecteditem="{Binding Path=SessionTypeID}" selectedvalue="{Binding Path=SessionTypeID}" tag="{Binding Path=SessionTypeID, Mode=TwoWay}" xmlns:x="#unknown" />


C#
string sql = @"SELECT * FROM Session WHERE SessionID = '" + id + "'";
           //  MessageBox.Show(sql);
           SQLiteCommand com = new SQLiteCommand(sql, conn);
           System.Data.DataSet ds = new System.Data.DataSet();
           SQLiteDataAdapter ad = new SQLiteDataAdapter(sql, conn);
           ad.Fill(ds);
           GridSessionData.DataContext = ds.Tables[0].DefaultView;

Here is the button XAML code:


<combobox x:name="comboBoxSessionDataSessionType" grid.column="1" grid.row="2" style="{DynamicResource ComboboxData}" itemssource="{Binding Path=SessionTypeID, Mode=TwoWay}" datacontext="{Binding SessionTypeName}" selecteditem="{Binding Path=SessionTypeID}" selectedvalue="{Binding Path=SessionTypeID}" tag="{Binding Path=SessionTypeID, Mode=TwoWay}" xmlns:x="#unknown">

Mika, here is how I filled the combobox:
C#
 string sql = @"SELECT SessionTypeID, SessionTypeName FROM SessionType WHERE Active = 1 ORDER BY SessionTypeName";
          
            SQLiteCommand com = new SQLiteCommand(sql, conn);
            System.Data.DataSet ds = new System.Data.DataSet();
            SQLiteDataReader dr = com.ExecuteReader();
            List<ComboBoxItem> list = new List<ComboBoxItem>();
            while (dr.Read())
            {
                ComboBoxItem item = new ComboBoxItem();
                item.Content = dr.GetValue(1).ToString();
                item.Tag = dr.GetValue(0).ToString();
                list.Add(item);
                }

            // add/edit selection
            ComboBoxItem itm = new ComboBoxItem();
            itm.Content = eesConstants.EESADDEDIT;
            itm.Tag = "";
            list.Add(itm);

            //  comboBoxSessionDataSessionType.Items.Add

(eesConstants.EESADDEDIT);
            comboBoxSessionDataSessionType.ItemsSource = list;


When I retrieve the Session entry, I know what the SessionTypeID is:

C#
ds.Tables[0].Rows[0]["SessionTypeID"].ToString()


Now that I have the SessionTypeID, how do I match it up with the correct entry in the SessionType combobox?

The combobox ItemSource is connected to the dataset where I'm getting the Session Data from:

XML
<ComboBox x:Name="comboBoxSessionDataSessionType" Grid.Column="1" Grid.Row="2" Style="{DynamicResource ComboboxData}" ItemsSource="{Binding Path=SessionTypeID, Mode=TwoWay
Posted
Updated 29-Sep-15 4:16am
v6
Comments
Richard Deeming 29-Sep-15 9:40am    
Your code is vulnerable to SQL Injection[^].

NEVER use string concatenation to build a SQL query. ALWAYS use a parameterized query.

When you loop through the items in a combo box you actually loop through the objects assigned to the combobox using the ItemsSource property. For example if the items source is a data view your loop would iterate through the datarow objects from the view. So when you call the ToString method it's called on the whole object.

Now in order to set the correct selected item in the combo box you have two options, use the index which is a more 'traditional' way but can be more difficult or you can also select the correct object from the data source and assign it into SelectedItem.

For example if you think about the dataview example, you can take any of the data rows from the view and assign that row into SelectedItem. You don't need to fetch the data row from the combo box at all, you can query the dataciew, loop through it, or what ever is the best way to find the correct object. This is one really big difference compared to for example Windows Forms.

You didn't post info how you actually fill the combo box but try setting the any of the actual objects in the ItemsSource to the SelectedItem and you'll see how it works.

ADDITION:

An example to select an item in the second combobox based on a data row value selected in the first combo box.

XAML
XML
<Window x:Class="CPWPF_C.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" 
        Height="350" 
        Width="525">
    <Grid >
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <ComboBox Grid.Column="0" Grid.Row="0" Name="FirstBox" DisplayMemberPath="FirstName" />
        <ComboBox Grid.Column="1" Grid.Row="0" Name="SecondBox" DisplayMemberPath="LastName" />
    </Grid>
</Window>

Code
C#
namespace CPWPF_C {
   /// <summary>
   /// Interaction logic for MainWindow.xaml
   /// </summary>
   public partial class MainWindow : Window {
      DataSet _dataSet = new DataSet();

      public MainWindow() {
         DataTable dataTable;

         InitializeComponent();

         // First table
         dataTable = new DataTable("First");
         
         dataTable.Columns.Add("Id", typeof(int));
         dataTable.Columns.Add("FirstName", typeof(string));

         dataTable.Rows.Add(1, "John");
         dataTable.Rows.Add(2, "Jane");
         dataTable.Rows.Add(3, "Someone");
         dataTable.Rows.Add(4, "Another");

         this._dataSet.Tables.Add(dataTable);

         // Second table
         dataTable = new DataTable("Second");

         dataTable.Columns.Add("Id", typeof(int));
         dataTable.Columns.Add("LastName", typeof(string));

         dataTable.Rows.Add(1, "Doe");
         dataTable.Rows.Add(2, "Doe");
         dataTable.Rows.Add(3, "Else");
         dataTable.Rows.Add(4, "Person");

         this._dataSet.Tables.Add(dataTable);

         // define item sources
         this.FirstBox.ItemsSource = this._dataSet.Tables["First"].DefaultView;
         this.SecondBox.ItemsSource = this._dataSet.Tables["Second"].DefaultView;

         // Wire the event
         this.FirstBox.SelectionChanged += FirstBox_SelectionChanged;
      }

      void FirstBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
         DataRowView dr = (DataRowView)e.AddedItems[0];
         int theRow;

         this._dataSet.Tables["Second"].DefaultView.Sort = "Id";
         theRow = this._dataSet.Tables["Second"].DefaultView.Find(dr["Id"]);
         this.SecondBox.SelectedItem = this._dataSet.Tables["Second"].DefaultView[theRow];
      }
   }
}
 
Share this answer
 
v2
Comments
Robert Kamarowski 29-Sep-15 10:16am    
Mika, here is how I filled the combobox:

Hide Copy Code
string sql = @"SELECT SessionTypeID, SessionTypeName FROM SessionType WHERE Active = 1 ORDER BY SessionTypeName";

SQLiteCommand com = new SQLiteCommand(sql, conn);
System.Data.DataSet ds = new System.Data.DataSet();
SQLiteDataReader dr = com.ExecuteReader();
List<comboboxitem> list = new List<comboboxitem>();
while (dr.Read())
{
ComboBoxItem item = new ComboBoxItem();
item.Content = dr.GetValue(1).ToString();
item.Tag = dr.GetValue(0).ToString();
list.Add(item);
}

// add/edit selection
ComboBoxItem itm = new ComboBoxItem();
itm.Content = eesConstants.EESADDEDIT;
itm.Tag = "";
list.Add(itm);

// comboBoxSessionDataSessionType.Items.Add

(eesConstants.EESADDEDIT);
comboBoxSessionDataSessionType.ItemsSource = list;


When I retrieve the Session entry, I know what the SessionTypeID is:


Hide Copy Code
ds.Tables[0].Rows[0]["SessionTypeID"].ToString()

Now that I have the SessionTypeID, how do I match it up with the correct entry in the SessionType combobox?

The combobox ItemSource is connected to the dataset where I'm getting the Session Data from:


Hide Copy Code
<combobox x:name="comboBoxSessionDataSessionType" itemssource="{Binding Path=SessionTypeID, Mode=TwoWay</div> <div id=" grid.row="2" grid.column="1" editdialogplaceholder"="">
Wendelius 29-Sep-15 13:48pm    
Not sure if I understand this correctly, but instead of creating new combo box items, why not utilize the data rows? Have a look at the updated solution.

The example tries to show how you can just select an existing row from a table's data view and set that DataRowView in the SelectedItem without ever knowing the index of the item in the combo box. So all the time the code is working with the data in the tables and it's not even investigating the selected indexes or looping through the items in the combo box.
Robert Kamarowski 30-Sep-15 12:00pm    
Got it! Thank you Mika.
Wendelius 30-Sep-15 12:19pm    
You're welcome :)
You don't need to loop through the collection. Have a look here: http://www.dotnetperls.com/combobox-wpf[^]
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900