2017-06-04 3 views
0

Ich brauche Hilfe mit diesem Teil meines Codes. Ich versuche hier 2 Dinge zu tun:Löschen von Daten in einer ComboBox, die Daten gebunden ist

1. Ich brauche meine ComboBox cmbTechSearch gefüllt mit einer Liste von Namen aus einer SQL-Datenbank abgerufen. Diese Namen gehören zu einem Objekt namens Tecnico. So weit, so gut. Aber wenn ich zweimal auf die ComboBox klicke, bekomme ich die Namen doppelt ... Und so weiter. Hinzufügen von cmbTechSearch.Items.Clear(); löste es nicht, weil die Box Daten gebunden war und eine Fehlermeldung auslöste. Also habe ich hinzugefügt cmbTechSearch.DataSource = null; das löste die Fehlermeldung aber löschte meine Box nicht. Auch nicht CmBTechSearch.ResetText(); Im Moment bin ich mir nicht sicher, wie ich es löschen soll, damit die Daten nicht dupliziert werden, wenn ich wieder auf die Box klicke.

2. bringt diese aus der SQL-Datenbank abgerufene Liste mehr als nur den angehängten Namen. Es bringt auch eine E-Mail für jedes Objekt. Und ich kann nicht herausfinden, wie man die mit dem gewählten Namen auf dieser ComboBox verbundene E-Mail erhält. Wohlgemerkt, E-Mail ist eine globale String-Variable, da ich sie in anderen Methoden innerhalb des Codes verwende. Dieser Teil ist kommentiert, weil es nicht funktioniert.

public void TechSearch_loaded (object sender, EventArgs e)

{

// alle diese drei Einträge sind angeblich die comboBox cmbTechSearch löschen; alle von ihnen scheitern, aber wenn ich die erste Zeile entfernen bekomme ich eine Fehlermeldung, dass es bereits einige an die Box gebunden Daten (aber nur, wenn ich ein zweites Mal klicken)

 cmbTechSearch.DataSource = null; 
     cmbTechSearch.Items.Clear(); 
     cmbTechSearch.ResetText(); 

// eine Klasse namens Tecnico und Alle Informationen zu diesem Objekt werden in einer SQL-Datenbank gespeichert. Dieser Teil füllt eine Liste von Tecnicos mit Informationen aus der Datenbank.

 List<Tecnico> tecnicos = new List<Tecnico>(); 
     tecnicos = bd.ProcuraPerfisTipo("TEC"); 

// dann bekomme ich eine Liste von Tecnicos und Abrufen von einem Attribute (Nome) für jede tecnico in der Liste

 List<String> TechSearch = new List<String>(); 

     foreach (Tecnico obj in tecnicos) 
     { 
      TechSearch.Add(obj.Nome); 
     } 

// schließlich bevölkere ich die comboBox mit den Informationen, die ich von der bekam Liste.

 cmbTechSearch.DataSource = TechSearch; 

     //email = cmbTechSearch.ToString(); 
    } 

Es gibt eine Klasse mit dem Namen Tecnico, ein anderer namens BDTicketSQL und eine andere namens iBDTicketSQL (die erste, die SQL db Aufruf und Updates, Abfragen und Einsätze laufen, während die zweite für die Schnittstelle verwendet wird). Diese Klassen sind alle außerhalb dieser Form. Ich bekomme nur ein Datum von ihnen, um das Formular mit allen Informationen zu füllen, die ich brauche.

Antwort

0

In Ordnung, also was Sie brauchen, um Ihren Aufwand zu reduzieren, ist DataBinding. Da Sie in Ihrer Frage Databinding erwähnt haben, gehe ich davon aus, dass Sie es wissen. Also werde ich schnell die Antwort durchgehen. Da Sie auch keine Plattform erwähnt haben, habe ich angenommen, dass es WPF ist, aber der Code kann nach WinRT oder UWP kopiert werden, wenn Sie möchten. Nur wenn es eine andere Plattform ist, lass es mich wissen im Bereich Link to full solution In case you wana skip

Ihre XAML: Ich habe grundlegende Bindung an Codebehind verwendet, um eine Menge von Klassen für eine Probe zu vermeiden. unten ist der Code:

<StackPanel Margin="20"> 
    <ComboBox x:Name="UserCombobox" 
       Height="20" 
       Width="300" 
       ItemsSource="{Binding DataFromSQLService,Mode=OneWay}" 
       SelectedItem="{Binding CurrentSelectedUser,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" 
       ItemTemplate="{StaticResource UserDataTemplate}" 
       SelectionChanged="UserCombobox_SelectionChanged"/> 

    <Button Content="Clear Combo" Height="30" Width="100" Margin="10" Click="ClearData"/> 

    <Button Content="Load Combo" Height="30" Width="100" Margin="10" Click="LoadData"/> 

    <TextBlock Text="{Binding CurrentSelectedUser.Name,Mode=OneWay}" HorizontalAlignment="Center"/> 

    <TextBlock Text="{Binding CurrentSelectedUser.Email,Mode=OneWay}" HorizontalAlignment="Center"/> 

</StackPanel> 

nun Ihre Window.Resources, wo Sie Ihre dataTemplate für Ihre Combobox Artikel setzen.

<Window.Resources> 
    <DataTemplate x:Key="UserDataTemplate"> 
     <StackPanel> 
      <TextBlock Text="{Binding Name}"/> 
     </StackPanel> 
    </DataTemplate> 
</Window.Resources> 

nun selbst die Ansicht binden, um es Code-Behind ist, so im Fenster Konformitätserklärung

DataContext = "{Binding RelativeSource={RelativeSource Self}}" 

Fügen Sie nun, dass die Ansicht bereit ist, lassen Sie sich schnell unseren Code hinter mir bereit.

Eine Dummy-Benutzerklasse Sie können dies durch Ihre Modellklasse ersetzen.

Jetzt erstellen Sie eine schnelle Eigenschaft, um den aktuell ausgewählten Benutzer zu halten.

private MyDummyUser currentSelectedUser; 

    public MyDummyUser CurrentSelectedUser 
    { 
     get { return currentSelectedUser; } 
     set { currentSelectedUser = value; RaisePropertyChanged(nameof(CurrentSelectedUser)); } 
    } 

Jetzt eine beobachtbare Sammlung erstellen Sie Ihre Daten aus der SQL-Dienst zu halten:

private ObservableCollection<MyDummyUser> dataFromSQLService; 
    public ObservableCollection<MyDummyUser> DataFromSQLService 
    { 
     get { return dataFromSQLService; } 
     set { dataFromSQLService = value; RaisePropertyChanged(nameof(DataFromSQLService)); } 
    } 

Jetzt INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged; 
    public void RaisePropertyChanged(string propertyName) 
    { 
     if (PropertyChanged != null) 
      PropertyChanged.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
    //if using c# 6.0 or later replace the above with 
    //public void RaisePropertyChanged(string propertyName)=> 
    //  PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 

nun einen Zuhörer zum combobox.SelectionChanged Event hinzufügen implementieren, so dass Sie wissen, wenn der ausgewählte Benutzer geändert wurde:

Erstellen Sie zwei Methoden: LoadData und ClearData.

private void ClearData(object sender, RoutedEventArgs e) 
    { 
     DataFromSQLService = null; 
    } 

    private void LoadData(object sender, RoutedEventArgs e) 
    { 
     List<MyDummyUser> someData = new List<MyDummyUser>() 
     { 
      new MyDummyUser("User 1","[email protected]"), 
      new MyDummyUser("User 2","[email protected]"), 
      new MyDummyUser("User 3","[email protected]"), 
      new MyDummyUser("User 4","[email protected]"), 
      new MyDummyUser("User 5","[email protected]"), 
      new MyDummyUser("User 6","[email protected]"), 
     }; 

     DataFromSQLService = new ObservableCollection<MyDummyUser>(someData); 
    } 

Bitte beachten Ich habe ein Beispiel für eine WPF verwendet, aber auch wenn Sie den Code für WinRT oder UWP verwenden möchten werde es, nur nicht vergessen, arbeiten zu wechseln Window.Resources mit Page.Resources auch, in UWP Sie kann x:Bind verwenden und mit x: Bind kann Ihnen helfen, die RelativeResource=self

+0

loszuwerden Danke für die Antwort. Das ist eine Menge zu verdauen ... Ich habe vergessen zu erwähnen, dass ich an Windows Forms arbeite. Macht das einen Unterschied? –

+0

Nun ja. Weil du in WinForms kein xaml hast. Die Datenbindung muss also auf andere Weise erfolgen. Also für die Anwendung der Datenbindung verwenden https://stackoverflow.com/q/2251075/3766231 –

+0

Ich habe nicht viel Erfahrung mit WinForms, aber ich werde versuchen, eine Probe für Sie zu bekommen. –

Verwandte Themen