Click here to Skip to main content
15,896,557 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
All right, I.m at wits end. I’m working with WPF and C#. I have an application (a simple checking account, book keeping application). I have 3 comboboxes (cboBroker, cboCatagory and cboSubCatagory) and 3 listboxes (lstBroker, lstCatagory and lstSubCatagory). Essentially, upon the “DropDownClosed” event handler on the comboboxes, the “ComboBox.Text” should be sent to and appear in the respective listbox. This works for cboBroker and cboSubCatagory but I encounter very weird behavior in the case of cboCatagory.

For instance, if I load the broker all is well; the SelectedItem in cboBroker is added to lstBroker. Next, if I load category, the Category. Text will be “ ” and lstCatagory will receive a blank line. I guess that makes sense except that apparently the SelectedItem in cboCatagory was not sent to cboCatagory.Text. Now, if I load the subcategory, again all is well, SubCatagory.Text is added to lstSubCatagory. Ok, now I go back to cboCategory and when when “DropDownClosed” is triggered low and behold the SelectedItem in cboSubCatagory appears in the second row of lstCatagory. What’s going on here? Over the past three days I’ve tried numerous approaches to resolve this issue but apparently WPF believes this is the behavior that should occur. Is something going on with routed events and if so why doesn’t it occur with the other two comboboxes and listboxes?

I’ve attached what I believe is the pertainent XAML code and C# code behind below:

XAML:
HTML
<Window x:Name="winTestScrolling" x:Class="TestListboxScrolling.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Test Scrolling" Height="450" Width="800" >    
<Grid >
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <WrapPanel x:Name="stkListBoxes" Width="Auto" MaxHeight="120"
Grid.Row="0" Margin="30,10,30,10" Orientation="Horizontal" removed="LightGreen" Grid.Column="1">
            <ListBox x:Name="lstBroker"  Width="125" Height="Auto" MinHeight="50" MaxHeight="100"
Margin="100,-110,0,5" ClipToBounds="True" />
            <ListBox x:Name="lstCatagory" Width="125" Height="Auto" MinHeight="50" MaxHeight="100" 
Margin="5,-110,0,5" ClipToBounds="True"/>
            <ListBox x:Name="lstSubCatagory" Width="125" Height="Auto" MinHeight="50" MaxHeight="100" 
Margin="5,-110,0,5" ClipToBounds="True"/>
        </WrapPanel>
        <WrapPanel x:Name="stkComboBoxes" Width="Auto" Height="Auto" 
                    Grid.Row="1" Grid.Column="1" Margin="29.6,4.6,30.4,15" Orientation="Horizontal">
<ComboBox x:Name="cboBroker" Width="125" Height="Auto" MinHeight="20"
Margin="100,-85,0,5" DropDownClosed="cboBroker_DropDownClosed" />
<ComboBox x:Name="cboCatagory"  Width="125" Height="Auto" MinHeight="20"
Margin="2,-85,0,5" DropDownClosed="cboCatagory_DropDownClosed"/>
<ComboBox x:Name="cboSubCatagory" Width="125" Height="Auto" MinHeight="20"
Margin="2,-85,0,0" DropDownClosed="cboSubCatagory_DropDownClosed" />
        </WrapPanel>
    </Grid>
</Window>

Code Behind:

C#
namespace TestListboxScrolling
{
    public partial class MainWindow : Window
{
        private void cboBroker_DropDownClosed(object sender, EventArgs e)
        {
            Broker = cboBroker.Text;
            lstBroker.Items.Add(Broker);
        }
        private void cboCatagory_DropDownClosed(object sender, EventArgs e)
        {
            Catagory = cboCatagory.Text;
            lstCatagory.Items.Add(Catagory);
        }
        private void cboSubCatagory_DropDownClosed(object sender, EventArgs e)
        {
            SubCatagory = cboSubCatagory.Text;
            lstSubCatagory.Items.Add(SubCatagory);
        }
    }
}
Posted
Updated 5-Aug-15 9:22am
v2
Comments
Sergey Alexandrovich Kryukov 5-Aug-15 15:47pm    
I did not dig into your problem, but want to give you one little hint. It seems to me that you are using string type for list elements of combo boxes. If this is so, and if you want to implement some operations related to the content of the elements, they should not be strings. The element's compile-time data type is System.Object. That means, that you can create any semantically sensible data types to be used as elements, not strings. The remaining problem is to bind these objects with the text shown in each element (it can have complicated template, but let's assume you need just the text). The simplest way to define such string is to override System.Object.ToString() in your data types.

Another question is: are your combo boxes data-bound? If they are, you should operate on data sources, not UI directly; if not, consider using binding-based approach.

—SA

I had to delete the 'removed="lightgreen"' from the grid and make the grid larger so it could be viewed correctly, but this code, based on your code works perfectly under VS 2012. You did declare Catagory as a string?

C#
public MainWindow()
            {
            InitializeComponent();

            cboBroker.Items.Add("Broker1");
            cboBroker.Items.Add("Broker2");
            cboBroker.Items.Add("Broker3");

            cboCatagory.Items.Add("Cat1");
            cboCatagory.Items.Add("Cat2");
            cboCatagory.Items.Add("Cat3");

            cboSubCatagory.Items.Add("Sub1");
            cboSubCatagory.Items.Add("Sub2");
            cboSubCatagory.Items.Add("Sub3");
            }

        string Broker;
        string Catagory;
        string SubCatagory;

        private void cboBroker_DropDownClosed(object sender, EventArgs e)
            {
            Broker = cboBroker.Text;
            lstBroker.Items.Add(Broker);
            }
        private void cboCatagory_DropDownClosed(object sender, EventArgs e)
            {
            Catagory = cboCatagory.Text;
            lstCatagory.Items.Add(Catagory);
            }
        private void cboSubCatagory_DropDownClosed(object sender, EventArgs e)
            {
            SubCatagory = cboSubCatagory.Text;
            lstSubCatagory.Items.Add(SubCatagory);
            }
 
Share this answer
 
Comments
Tipton Tyler 6-Aug-15 12:06pm    
Thank you all for your suggestions. I apologize for the incomplete XAML code. In an attempt to mineralize, I left a few things in that weren't pertinent and left out a few that were. As suggested I ran the "code behind" in the manner suggested by arussell and everything worked as expected. I then did what I probably should have before submitting the question and began adding the remainder of the code for the full application piece by piece. It only took one try to isolate the problem.
The full application loads the brokers, categories and subcategories from a database. I use a datareader to load the comboboxes. The pertinent code follows:

sql = "SELECT Broker FROM tabBroker ORDER BY Broker";
cboBroker = cboFiller.FillBox(sql, cboBroker);

public ComboBox FillBox(string sql, ComboBox cboBox)
{
string Sql = sql;
string strConnect = "Data Source=(LocalDB)\\MSSQLLocalDB;Initial
Catalog=database;Integrated Security=True";
SqlConnection con = null;
SqlDataReader reader = null;
try
{
con = new SqlConnection(strConnect);
con.Open();

SqlCommand com = new SqlCommand(Sql, con);
reader = com.ExecuteReader();
while (reader.Read())
{ cboBox.Items.Add(reader.GetString(0)); }
}
catch (SqlException Ex)
{ MessageBox.Show("Failure to load " + cboBox + "\n + " + Ex); }
finally
{ if (reader != null) { reader.Close(); } con.Close(); }
return cboBox;
}

The weird WPF behavior occurs when the comboboxes are loaded in this manner. I suspect SAKryukov suggestion is pertinent but I'm not sure how to go about implementing the solution.
Well, both the inline method that is commented out, and the LoadComboBox work for me. Only difference is I use SqlConnectionStringBuilder() which shouldn't matter. As long as your combobox displays the string when you click on it it should be working.

Try looking for every reference of the combobox in question, and make sure nothing is clearing it when you don't expect.

My test table just has brokers as nchar(100)


public partial class MainWindow : Window
       {
       public MainWindow()
           {
           InitializeComponent();

           try
               {

               /*
               cboBroker.Items.Add("Broker1");
               cboBroker.Items.Add("Broker2");
               cboBroker.Items.Add("Broker3");
                * */
               /*
               SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
               builder["Data Source"] = "HY201486\\Express2012";
               builder["integrated Security"] = true;
               builder["Initial Catalog"] = "ajrtest";
               SqlConnection con = new SqlConnection(builder.ConnectionString);
               con.Open();
               SqlCommand cmd = new SqlCommand("select * from Broker order by broker", con);
               SqlDataReader reader = cmd.ExecuteReader();

               while (reader.Read())
                   {
                   cboBroker.Items.Add(reader.GetString(0));
                   }

               con.Close();
                * */

               LoadComboBox("select * from Broker order by broker", cboBroker);

               cboCatagory.Items.Add("Cat1");
               cboCatagory.Items.Add("Cat2");
               cboCatagory.Items.Add("Cat3");

               cboSubCatagory.Items.Add("Sub1");
               cboSubCatagory.Items.Add("Sub2");
               cboSubCatagory.Items.Add("Sub3");
               }

           catch (Exception ex)
               {
               MessageBox.Show("Error: " + ex.Message);
               }

           }

       string Broker;
       string Catagory;
       string SubCatagory;

       private void LoadComboBox(string sql, ComboBox cboBox)
           {
           try
               {
               SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder();
               builder["Data Source"] = "HY201486\\Express2012";
               builder["integrated Security"] = true;
               builder["Initial Catalog"] = "ajrtest";
               SqlConnection con = new SqlConnection(builder.ConnectionString);
               con.Open();
               SqlCommand cmd = new SqlCommand(sql, con);
               SqlDataReader reader = cmd.ExecuteReader();

               while (reader.Read())
                   {
                   cboBox.Items.Add(reader.GetString(0));
                   }

               con.Close();
               }
           catch (Exception ex)
               {
               MessageBox.Show("Error: " + ex.Message);
               }

           }
 
Share this answer
 
First, thank you arussel for your helpful comments. I have found and am now able to recreate the bazaar behavior I experienced with the WPF comboboxes. It all boils down to sloppy use of cut and paste operations in creating a new UI. Essentially, in creating cboCatagory I copied and pasted the XAML code for cboSubCatagory and then changed SubCategory to Category in the appropriate places. This action also apparently created a “DropDownClosed” event and corresponding “DropDownClosed” event handler for cboCatagory. In creating the code behind, again I must have copied and pasted a second copy of the “DropDownClosed” event handler, i.e. cboCatagory_DropDownClosed_1. Somehow this 2nd copy contained the objectionable statement:

Category = cboSubCategory.Text;

The attached code (XAML and C# code behind) recreates the bazaar behavior I was observing. Again, thank you for your input it lead ne in the right direction and encouraged me to follow through to find what was going on.

I actually developed this “on the side” application to investigate another problem; the scrolling behavior of the WPF listbox (in so doing I spent the last 10 days trying to get it to work). I will pose my scrolling problem in another question.

ttyler

XAML:

XML
<window x:class="ComboBoxTester.MainWindow" xmlns:x="#unknown">
       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Reconstruct" Height="450" Width="800">
    <grid x:name="grdContent" horizontalalignment="Left" background="AliceBlue" margin="10">
        <grid.rowdefinitions>
            <rowdefinition height="Auto" minheight="150" />
            <rowdefinition height="*" />
        </grid.rowdefinitions>
        <grid.columndefinitions>
            <columndefinition width="150" />
            <columndefinition width="640" />
        </grid.columndefinitions>
        <stackpanel x:name="stkButtons" width="Auto" height="Auto" margin="5,5,5,5">
            <button x:name="btnReturn" content="Return" horizontalalignment="Left" verticalalignment="Top">
                        MinWidth="75" Height="35" Margin="5,10,0,5" Click="btnReturn_Click"/>
        </button></stackpanel>
        <wrappanel x:name="wrpListBoxes" width="Auto" maxheight="120" grid.row="0" grid.column="1">
                   Margin="30,10,30,10" Orientation="Horizontal" Background="AliceBlue">
            <listbox x:name="lstBroker" width="125" height="Auto" minheight="50">
                    Margin="100,10,0,5" HorizontalAlignment="Center" VerticalAlignment="Center" 
                    ScrollViewer.HorizontalScrollBarVisibility="Hidden" 
                    ScrollViewer.VerticalScrollBarVisibility="Hidden" Background="LightYellow"/>
            <listbox x:name="lstCatagory" width="125" height="Auto" minheight="50">
                    Margin="5,10,0,5" HorizontalAlignment="Center" VerticalAlignment="Center" 
                    ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                    ScrollViewer.VerticalScrollBarVisibility="Hidden" Background="LightYellow"/>
            <listbox x:name="lstSubCatagory" width="125" height="Auto" minheight="50">
                    Margin="5,10,0,5" HorizontalAlignment="Center" VerticalAlignment="Center"
                    ScrollViewer.HorizontalScrollBarVisibility="Hidden"
                    ScrollViewer.VerticalScrollBarVisibility="Hidden" Background="LightYellow"/>
        </listbox></listbox></listbox></wrappanel>
        <wrappanel x:name="wrpComboBoxes" width="Auto" height="Auto" grid.row="1" grid.column="1">
                   Margin="30,5,30,10" Orientation="Horizontal" Background="AliceBlue" >
            <combobox x:name="cboBroker" width="125" height="20" margin="100,10,0,0">
                   HorizontalAlignment="center" VerticalAlignment="Center" Background="PaleGreen"
                   ItemsSource="{Binding Path=EntryList}" DisplayMemberPath="Broker" 
                   DropDownClosed="cboBroker_DropDownClosed" />
            <combobox x:name="cboCatagory" width="125" height="20" margin="5,10,0,0">
                   HorizontalAlignment="Left" VerticalAlignment="Top" Background="PaleGreen"
                   ItemsSource="{Binding Path=EntryList}" DisplayMemberPath="Catagory" 
                   DropDownClosed="cboCatagory_DropDownClosed_1" />
            <combobox x:name="cboSubCatagory" width="125" height="20" margin="5,10,0,0">
                   HorizontalAlignment="Left" VerticalAlignment="Top" Background="PaleGreen"
                   ItemsSource="{Binding Path=EntryList}" DisplayMemberPath="SubCatagory" 
                   DropDownClosed="cboSubCatagory_DropDownClosed" />
        </combobox></combobox></combobox></wrappanel>
    </grid>
</window>


Code behind:

C#
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;


namespace ComboBoxTester
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        string Broker;
        string Catagory;
        string SubCatagory;
        int i = 0;
        string Num;
        Transactions transaction = new Transactions();
        List<transactions> EntryList = new List<transactions>();

        public MainWindow()
        {
            InitializeComponent();

//      Create a list of Brokers, Catagories and SubCatagories to add to comboboxes

            for(i= 1; i<=10; i++)
            {
                Num = i.ToString();       

                Broker = "Broker" + Num;
                Catagory = "Catagory" + Num;
                SubCatagory = "SubCatagory" + Num;

                EntryList.Add(new Transactions() { Broker = Broker, Catagory = Catagory, SubCatagory = SubCatagory });
            }
            cboBroker.ItemsSource = EntryList;
            cboCatagory.ItemsSource = EntryList;
            cboSubCatagory.ItemsSource = EntryList;
        }
        private void btnReturn_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void cboBroker_DropDownClosed(object sender, EventArgs e)
        {
            Broker = cboBroker.Text;
            lstBroker.Items.Add(Broker);
        }

        private void cboCatagory_DropDownClosed(object sender, EventArgs e)
        {
            Catagory = cboCatagory.Text;
            lstCatagory.Items.Add(Catagory);
        }

        private void cboSubCatagory_DropDownClosed(object sender, EventArgs e)
        {
            SubCatagory = cboSubCatagory.Text;
            lstSubCatagory.Items.Add(SubCatagory);
        }

        private void cboCatagory_DropDownClosed_1(object sender, EventArgs e)
        {
            Catagory = cboSubCatagory.Text;
            lstCatagory.Items.Add(Catagory);
        }

//  Create a Transaction type to add to List<transaction>

        public class Transactions
        {
            public string Broker { get; set; }
            public string Catagory { get; set; }
            public string SubCatagory { get; set; }
        }
    }
}
</transaction></transactions></transactions>
 
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