2016-04-20 18 views
1

Wie kann ich programmgesteuert andere Elemente in einer ListBox auswählen, indem ich auf ein Element in derselben ListBox klicke? Dies ist ein C# winforms-Projekt.Mehrere ListBox-Elemente in derselben ListBox mit einem Klick auswählen

Zum Beispiel, wenn ich unten auf Kleidung klicke, müssten Hosen und Hemden automatisch hervorgehoben werden. Das Gleiche gilt für Autoteile, die Reifen und Getriebe hervorheben.

Clothes 
Pants 
Tires 
Shirts 
Transmissions 
Auto Parts 

Ich habe meine ListBox an eine Datasource gebunden (itemList) und ich versuchte, einen „itemIndex“ zu jedem Element in meiner Liste hinzufügen, so konnte ich die Sortierung behandeln (ich bin sicher, es ist wahrscheinlich ein besserer Weg ?) was zu der Zeit für mich einen Sinn ergab, aber ich konnte nicht herausfinden, wie ich es außerhalb meines Kopfes funktioniere ...

Hier ist mein aktueller Code, aber bitte bare mit mir Ich lerne immer noch das . Irgendwelche Vorschläge wären fantastisch.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace listBox_test 
{ 
public partial class Form1 : Form 
{ 
    BindingList<Item> itemList = new BindingList<Item>(); 

    public Form1() 
    { 
     InitializeComponent(); 
     ShowData(); 
    } 
    private void ShowData() 
    { 
     this.listBox1.DataSource = itemList; 
     this.listBox1.DisplayMember = "ItemName"; 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     AddItem(itemIndex: 0, itemName: "Clothes", itemPrice: 0.95); 
     AddItem(itemIndex: 1, itemName: "Pants", itemPrice: 0.95); 
     AddItem(itemIndex: 2, itemName: "Tires", itemPrice: 0.95); 
     AddItem(itemIndex: 3, itemName: "Shirts", itemPrice: 0.95); 
     AddItem(itemIndex: 4, itemName: "Transmissions", itemPrice: 0.95); 
     AddItem(itemIndex: 5, itemName: "Auto Parts", itemPrice: 0.95); 
    } 

    // Add an item to the list 
    private void AddItem(int itemIndex, string itemName, double itemPrice) 
    { 
     itemList.Add(new Item(itemIndex, itemName, itemPrice)); 
    } 

    private void listBox1_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     // SelectChild(); ?? 
    } 
} 
public class Item 
{ 
    public int ItemIndex { get; set; } 
    public string ItemName { get; set; } 
    public double ItemPrice { get; set; } 
    public Item(int itemIndex, string itemName, double itemPrice) 
    { 
     ItemIndex = itemIndex; 
     ItemName = itemName; 
     ItemPrice = itemPrice; 
    } 
} 
} 

Antwort

1

Sie müssen irgendeine Art von Beziehung haben (wahrscheinlich eine Taste, um mehrere Werte) deklariert zwischen ihnen, so dass Ihre Programm weiß, welcher (n) Artikel zu welchem ​​Artikel gehört (

)

Als Beispiel wird unten für string zu string[] Verhältnis unter Verwendungimplementiert:

Dictionary<string, string[]> dict = new Dictionary<string, string[]>(){ 
    {"Clothes", new string[] {"Pants","Shirts"}}, 
    {"Auto Parts", new string[] {"Tires","Transmissions"}} 
}; 

Dann, indem Sie Ihre ListBox.SelectionMode als MultiSimple setzen, und auf der Grundlage der Key (string), können Sie dann die Value (string[]) wählen könnte durch die Verwendung ListBox.SetSelected

Um das umzusetzen, was Sie in vollem Umfang möchten, aber ich fand es ganz tricky - vor allem, wenn Sie SelectedIndex Ereignis verwenden. Es gibt mindestens zwei andere Dinge, die Sie beachten müssen:

  1. Wenn Sie etwas in der SelectedIndexChanged Ereignis handelr wählen, wird es das Programm führen auslösen andereSelectedIndexChanged. Wenn dies nicht sorgfältig gehandhabt wird, kann dies aufgrund von Rekursionsaufrufen zu einer Ausnahme von StackOverflow führen.
  2. Möglicherweise möchten Sie einige Standardfunktionalität für Artikel haben, die nicht in der key Liste sind (wie Shirts). Um dies zu tun, müssen Sie möglicherweise notieren, was das letzte ausgewählte Element ist. Aber leider nicht die SelectedItems und SelectedIndices von ListBox gehen nicht durch Selektion chronologische Ordnung, sondern durch sequentielle Ordnung. Daher können Sie weder aus SelectedItems noch aus SelectedIndices schließen, was das zuletzt ausgewählte Element ist. Daher müssen Sie möglicherweise für das letzte (einzelne) ausgewählte Element einen eigenen "Speicher" implementieren.

Betrachtet man einige Dinge über die endgültige, Safe, Umsetzung wie folgt aussehen (kommentiert):

//Creates relationship 
Dictionary<string, string[]> dict = new Dictionary<string, string[]>(){ 
    {"Clothes", new string[] {"Pants","Shirts"}}, 
    {"Auto Parts", new string[] {"Tires","Transmissions"}} 
}; 

private bool isProcessingSelection = false; //prevents stack overflow 
List<string> listBox1_lastSelections = new List<string>(); //creates memory 

private void listBox1_SelectedIndexChanged(object sender, EventArgs e) {    
    if (isProcessingSelection) //to prevent stack overflow exception because of recursive call 
     return; 

    isProcessingSelection = true; //set true whenever processing 

    List<string> currentSelections = listBox1.SelectedItems.Cast<string>().ToList(); 
    string lastSelection = listBox1_lastSelections.Count > currentSelections.Count ? 
     listBox1_lastSelections.Except(currentSelections).FirstOrDefault() : 
     currentSelections.Except(listBox1_lastSelections).FirstOrDefault(); 
    //get the last selected item by comparison of current and last selection 

    int index = listBox1.Items.IndexOf(lastSelection); //the last selected index 

    for (int i = 0; i < listBox1.Items.Count; ++i) { 
     if (i == index) //do not process the last selected index 
      continue; 
     listBox1.SetSelected(i, false); //make everything else false 
    } 

    if (dict.ContainsKey(lastSelection)) { //if the last selection is among the item in the dictionary, highlight the rests 
     string[] related = dict[lastSelection]; 
     for (int i = 0; i < listBox1.Items.Count; ++i) 
      if (related.Contains(listBox1.Items[i].ToString())) 
       listBox1.SetSelected(i, true); 
    } 

    listBox1_lastSelections = listBox1.SelectedItems.Cast<string>().ToList(); //update the last selection 

    isProcessingSelection = false; //prepare for the next, non recursive call 
} 
+1

Ausgezeichnete Erklärung! Dank dafür. Jede Eingabe über die Tastatur stürzt das Programm ab, aber ich denke, es sollte eine einfache Lösung sein – Giovanni

0

müssen Sie eine Schleife durch Ihre listbox und Set ausgewählt true

for (int i = 0; i < myListBox.Items.Count;i++) 
    { 
     myListBox.SetSelected(i, true); 
    } 
Verwandte Themen