I have a WPF application with a number of comboboxes that tie together. When I switch comboboxx #1, combobox #2 switches, etc.
Here is the xaml for the 2 comboboxes:
<ComboBox Grid.Row="1" Height="23" HorizontalAlignment="Right" Margin="0,12,286,0" ItemsSource="{Binding}" Name="CboDivision" VerticalAlignment="Top" Width="120" SelectionChanged="CboDivision_SelectionChanged" />
<ComboBox Height="23" HorizontalAlignment="Right" Margin="0,9,32,0" Name="CboCustomerList" ItemsSource="{Binding}" VerticalAlignment="Top" Width="120" SelectionChanged="CboCustomerList_SelectionChanged" Grid.Row="1" />
CboDivision gets populated at the beginning and doesnt need a reset. HEre is the code that calls the change in division, which should trigger a change in customer:
private void CboDivision_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
division = CboDivision.SelectedValue.ToString();
CboCustomerList.ItemsSource = null;
BackgroundWorker customerWorker = new BackgroundWorker();
customerWorker.DoWork += new DoWorkEventHandler(FillCustomers);
customerWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(customerWorker_RunWorkerCompleted);
FillCustomers(null, null);
}
When I do an index change it calls a backgroundworker which calls the following code:
private void FillCustomers(object sender, DoWorkEventArgs e)
{
string connectionString = Settings.Default.ProdConnectionString;
SqlConnection connection = new SqlConnection(connectionString);
SqlCommand SqlCmd = new SqlCommand();
Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait;
SqlCmd.CommandType = CommandType.StoredProcedure;
SqlCmd.Parameters.Add("@division", SqlDbType.NVarChar).Value = division;
SqlCmd.Connection = connection;
SqlCmd.CommandText = "sp_GetCustomers";
SqlDataReader reader = null;
connection.Open();
reader = SqlCmd.ExecuteReader();
List<string> result = new List<string>();
while (reader.Read())
{
result.Add(reader["NAME"].ToString());
}
e.Result = result;
}
The problem is that i am unable to switch selections on CboDivision and have CboCustomerList clear and reload new values into it. Is it the way I'm binding the values in the xaml? How can I have a change in CboDivision cause a clearing of CboCustomerList items, then the execution of the filling routine?
i am currently resetting the combobox with:
CboCustomerList.SelectedIndex = -1;
but this just appends the new cbocustomerlist query to the end I also tried
CboCustomerList.Items.Clear()
but that just returns a null reference error after the box is refilled and the user selects an item.
Well, you didn't post all of your code, but one problem is that you are not invoking your worker thread.
Replace FillCustomers(null, null)
with customerWorker.RunWorkerAsync()
.
private void CboDivision_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
division = CboDivision.SelectedValue.ToString();
CboCustomerList.ItemsSource = null;
BackgroundWorker customerWorker = new BackgroundWorker();
customerWorker.DoWork += new DoWorkEventHandler(FillCustomers);
customerWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(customerWorker_RunWorkerCompleted);
customerWorker.RunWorkerAsync(); // <-- this
}
Let me know if this helps. If there is still more problem, please post the rest of your code.
There are details of code you didn't show. However, here is an example that works: two combos, what that is populated at the beginning, and a second that is populated each time the selection changes in the first. Notice that the data is fetched in a background worker, just as in your case.
XAML
<Window x:Class="CombosRefresh.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.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ComboBox Name="CboDivisions" ItemsSource="{Binding}" Grid.Row="0" Margin="5" />
<ComboBox Name="CboList" ItemsSource="{Binding}" Grid.Row="1" Margin="5" />
</Grid>
</Window>
C#
public partial class MainWindow : Window
{
private BackgroundWorker bw = new BackgroundWorker();
public MainWindow()
{
InitializeComponent();
CboDivisions.DataContext = new List<string>() { "red", "blue", "green" };
CboDivisions.SelectionChanged += CboDivisions_SelectionChanged;
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
}
void CboDivisions_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var division = CboDivisions.SelectedValue as string;
bw.RunWorkerAsync(division);
}
void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
CboList.DataContext = e.Result as List<string>;
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
var division = e.Argument as string;
var r = new Random();
var result = new List<string>();
for(int i = 0; i < r.Next(0, 10); ++i)
{
result.Add(string.Format("{0} #{1}", division, i+1));
}
e.Result = result;
}
}
replace the wrong FillCustomers(null, null);
code
with: customerWorker.RunWorkerAsync();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With