2015-05-08 9 views
8

Mam aplikację WPF z wieloma comboboxami, które są powiązane. Kiedy przełączyć comboboxx # 1, # 2 combobox przełączniki itpCzyszczenie i uzupełnianie związanego pola kombi

Oto XAML za 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 zostanie wypełniona na początku i nie robi potrzeba resetu. Oto kod, który wywołuje zmiany w podziale, co powinno spowodować zmianę klienta:

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); 

} 

Kiedy zrobić zmiany indeksu wywołuje BackgroundWorker który wywołuje następujący kod:

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; 


    } 

Problem polega na tym, że nie mogę zmienić zaznaczeń w CboDivision i mieć wyczyść CboCustomerList i załadować do niego nowe wartości. Czy to sposób w jaki wiążę wartości w Xaml? Jak mogę zmienić CboDivision, powodując wyczyszczenie elementów CboCustomerList, a następnie wykonanie procedury wypełniania?

Jestem obecnie resetowania combobox z:

CboCustomerList.SelectedIndex = -1; 

ale to tylko dodaje nowe zapytanie cbocustomerlist do końca Próbowałem też

CboCustomerList.Items.Clear() 

ale że po prostu zwraca null reference Błąd po pudełko zostanie ponownie napełnione, a użytkownik wybierze przedmiot.

+1

Opcja 'NullReferenceException' jest wyrzucany z powodu ostatniej instrukcji w' metody FillCustomers' oraz fakt, że w 'metody CboDivision_SelectionChanged' ty dzwonisz' FillCustomers (null , null) '(druga' null' jest przypisana do parametru 'e'). W ten sposób faktycznie nie korzystasz z pracownika - w tym celu powinieneś wywołać 'customerWorker.RunWorkerAsync()'. – Grx70

+0

@Matt Jacobi ma rację mówiąc, że wątek roboczy nigdy się nie uruchamia, czy jest jakiś kod? Jeśli jesteś w stanie wywoływać wątek roboczy, co stanie się z obsługą do jego zakończenia?Zamiast ustawiać ItemsSource na wartość null, czy próbowałeś opróżnić kolekcję, do której jest ona przypisana? – User92

Odpowiedz

4

Cóż, nie pisać cały kod, ale problemem jest to, że nie powołując swój wątku roboczego.

Wymień FillCustomers(null, null) na 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 
} 

Daj mi znać, jeśli to pomoże. Jeśli nadal występuje problem, opublikuj resztę kodu.

3

Istnieją szczegóły kodu, który nie został wyświetlony. Oto przykład, który działa: dwa kombinacje, co jest zapełniane na początku, i drugi, który zapełniany jest za każdym razem, gdy selekcja zmienia się w pierwszym. Zauważ, że dane są pobierane w tle w tle, tak jak w twoim przypadku.

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; 
     } 
    } 
+0

na e.Result = wynik; Otrzymuję zerowy błąd odniesienia. Jakie dane powinienem pokazać, aby uzyskać odpowiedź? – rigamonk

+0

Co oznacza, że ​​nie skopiowano kodu, który pokazałem. Przetestowałem to przed opublikowaniem go tutaj. Niestety nie mogę załączać plików, aby pokazać cały projekt, ale nie ma nic poza tym. –

2

wymienić źle FillCustomers(null, null); kod z: customerWorker.RunWorkerAsync();

Powiązane problemy