2008-12-18 5 views
28

Ich habe eine ListBox und ich möchte jedem Element in der Liste ein Kontextmenü hinzufügen. Ich habe die "Lösung" gesehen, um mit der rechten Maustaste ein Element auszuwählen und das Kontextmenü zu unterdrücken, wenn es sich um Leerraum handelt, aber diese Lösung fühlt sich schmutzig an.Wie kann ich einem ListBoxItem ein Kontextmenü hinzufügen?

Kennt jemand einen besseren Weg?

+0

Können Sie es nicht auf andere Weise entwerfen? Ich kann mir keine solche Benutzeroberfläche vorstellen ... Ich würde nie daran denken, mit der rechten Maustaste auf einen Listeneintrag zu klicken. – Gishu

+0

Sind Sie auch in Winforms oder WPF? Die Antworten können davon abhängig sein. – Gishu

Antwort

4

Auf diese Weise das Menü neben der Maus öffnet sich

private string _selectedMenuItem; 
private readonly ContextMenuStrip collectionRoundMenuStrip; 

public Form1() 
{ 
    var toolStripMenuItem1 = new ToolStripMenuItem {Text = "Copy CR Name"}; 
    toolStripMenuItem1.Click += toolStripMenuItem1_Click; 
    var toolStripMenuItem2 = new ToolStripMenuItem {Text = "Get information on CR"}; 
    toolStripMenuItem2.Click += toolStripMenuItem2_Click; 
    collectionRoundMenuStrip = new ContextMenuStrip(); 
    collectionRoundMenuStrip.Items.AddRange(new ToolStripItem[] {toolStripMenuItem1, toolStripMenuItem2 }); 
    listBoxCollectionRounds.MouseDown += listBoxCollectionRounds_MouseDown; 
} 

private void toolStripMenuItem2_Click(object sender, EventArgs e) 
{ 
    var info = GetInfoByName(_selectedMenuItem); 
    MessageBox.Show(info.Name + Environment.NewLine + info.Date); 
} 

private void toolStripMenuItem1_Click(object sender, EventArgs e) 
{ 
    Clipboard.SetText(_selectedMenuItem); 
} 

private void myListBox_MouseDown(object sender, MouseEventArgs e) 
{ 
    if (e.Button != MouseButtons.Right) return; 
    var index = myListBox.IndexFromPoint(e.Location); 
    if (index != ListBox.NoMatches) 
    { 
     _selectedMenuItem = listBoxCollectionRounds.Items[index].ToString(); 
     collectionRoundMenuStrip.Show(Cursor.Position); 
     collectionRoundMenuStrip.Visible = true; 
    } 
    else 
    { 
     collectionRoundMenuStrip.Visible = false; 
    } 
} 
4

Es gibt keinen anderen Weg: das Kontextmenü gehört nicht dem Element in der Listbox, sondern der Listbox selbst. Es ähnelt dem TreeView-Steuerelement, das auch das Kontextmenü anstelle des Treenodes besitzt. Wenn ein Element in der Listbox ausgewählt ist, legen Sie das Kontextmenü der Listbox entsprechend dem ausgewählten Element fest.

27

Nur um ein wenig weiter zu machen, was Frans gesagt hat ... Obwohl die ListBox den ContextMenuStrip besitzt, können Sie die Elemente in der Menüleiste immer noch anpassen, wenn sie geöffnet wird. Somit wird der Inhalt basierend auf der Mausposition innerhalb der Listbox angepasst.
Das folgende Beispiel wählt das Element in der Listbox basierend auf einem rechten Mausklick aus und passt dann einen Kontextmenüstreifen basierend auf dem Element an, auf das der Benutzer mit der rechten Maustaste geklickt hat. Dies ist ein einfaches Beispiel, aber sollten Sie gehen bekommen: ein Listenfeld zu einem Formular hinzufügen und fügen Sie diesen Code:

print("  #region Private Members 
    private ContextMenuStrip listboxContextMenu; 
    #endregion 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     //assign a contextmenustrip 
     listboxContextMenu = new ContextMenuStrip(); 
     listboxContextMenu.Opening +=new CancelEventHandler(listboxContextMenu_Opening); 
     listBox1.ContextMenuStrip = listboxContextMenu; 

     //load a listbox 
     for (int i = 0; i < 100; i++) 
     { 
      listBox1.Items.Add("Item: " + i); 
     } 
    } 

    private void listBox1_MouseDown(object sender, MouseEventArgs e) 
    { 
     if (e.Button == MouseButtons.Right) 
     { 
      //select the item under the mouse pointer 
      listBox1.SelectedIndex = listBox1.IndexFromPoint(e.Location); 
      if (listBox1.SelectedIndex != -1) 
      { 
       listboxContextMenu.Show(); 
      }     
     } 
    } 

    private void listboxContextMenu_Opening(object sender, CancelEventArgs e) 
    { 
     //clear the menu and add custom items 
     listboxContextMenu.Items.Clear(); 
     listboxContextMenu.Items.Add(string.Format("Edit - {0}", listBox1.SelectedItem.ToString())); 
    } "); 

Hoffnung, die helfen. -Mike

+0

Sehr nützlich! Danke vielmals! – asmo

+0

Ich bekomme einen Fehler, dass listboxContextMenu_Opening nicht im aktuellen Kontext existiert. –

1

wenn es nur eine Frage der Aktivierung oder Kontextmenüelemente zu deaktivieren, kann es effizienter sein, nur es tun, wenn das Kontextmenü eher ins Leben gerufen wird, als jedes Mal der Listenfeld Auswahl Änderungen:

myListBox.ContextMenu.Popup += new EventHandler(myContextPopupHandler); 


private void myContextPopupHandler(Object sender, System.EventArgs e) 
{ 
    if (SelectedItem != null) 
    { 
     ContextMenu.MenuItems[1].Enabled = true; 
     ContextMenu.MenuItems[2].Enabled = true; 
    } 
    else 
    { 
     ContextMenu.MenuItems[1].Enabled = false; 
     ContextMenu.MenuItems[2].Enabled = false; 
    } 
} 
4

In XAML zeigt es wie folgt aus:

<ListBox> 
    <ListBox.ContextMenu> 
     <ContextMenu> 
      <MenuItem Header="Add User..."/> 
      <MenuItem Header="Edit..."/> 
      <MenuItem Header="Disable"/> 
     </ContextMenu> 
    </ListBox.ContextMenu> 
</ListBox> 
1

dies am besten ist ...

using System.Windows.Forms; 

ContextMenuStrip menu; 

this.menu.Items.AddRange(new ToolStripItem[] { this.menuItem }); 
this.listBox.MouseUp += new MouseEventHandler(this.mouse_RightClick); 

private void mouse_RightClick(object sender, MouseEventArgs e) 
{ 
    int index = this.listBox.IndexFromPoint(e.Location); 
    if (index != ListBox.NoMatches) 
    { 
     menu.Visible = true; 
    } 
    else 
    { 
     menu.Visible = false; 
    } 
} 
0
//Create and Initialize the contextMenuStrip component 
contextMenuStrip_ListaAulas = new ContextMenuStrip(); 

//Adding an Item 
contextMenuStrip_ListaAulas.Items.Add("Modificar"); 

//Binding the contextMenuStrip with the ListBox 
listBox_Aulas.ContextMenuStrip = contextMenuStrip_ListaAulas; 

//The solution below 
if (e.Button == System.Windows.Forms.MouseButtons.Right) 
{ 
    //select the item under the mouse pointer 
    listBox_Aulas.SelectedIndex = listBox_Aulas.IndexFromPoint(e.Location); 

    //if the selected index is an item, binding the context MenuStrip with the listBox 
    if (listBox_Aulas.SelectedIndex != -1) 
    { 
     listBox_Aulas.ContextMenuStrip = contextMenuStrip_ListaAulas; 
    } 
    //else, untie the contextMenuStrip to the listBox 
    else 
    { 
     listBox_Aulas.ContextMenuStrip = null; 
    } 
} 
4

Und hier ist meine Lösung:

listBox_Usernames.ContextMenuStrip = contextMenuStripRemove; 

    listBox_Usernames.MouseUp += new MouseEventHandler(listBox_Usernames_MouseUp); 

    void listBox_Usernames_MouseUp(object sender, MouseEventArgs e) 
    { 
     int index = listBox_Usernames.IndexFromPoint(e.Location); 

     if (e.Button == System.Windows.Forms.MouseButtons.Right) 
     { 
      if (index != ListBox.NoMatches) 
      { 
       if (listBox_Usernames.SelectedIndex == index) 
       { 
        listBox_Usernames.ContextMenuStrip.Visible = true; 
       } 
       else 
       { 
        listBox_Usernames.ContextMenuStrip.Visible = false; 

       } 
      } 
      else 
      { 
       listBox_Usernames.ContextMenuStrip.Visible = false; 
      } 
     } 
     else 
     { 
      listBox_Usernames.ContextMenuStrip.Visible = false; 

     } 
    } 
0

ich so tun, das funktioniert, Großartig und schnell für mich.

private void contextMenuStrip1_Opening(object sender, CancelEventArgs e) 
    { 
     if (Listbox.SelectedItem == null) 
      e.Cancel = true; 
    } 
0

In einer Zeile Code (mehr für die Bindung):

var datasource = new BindingList<string>(new List<string>(new string[] { "item1" })); 
listbox.DataSource = datasource ; 
listbox.ContextMenu = new ContextMenu(
    new MenuItem[] { 
     new MenuItem("Delete", 
      new EventHandler((s,ev) => 
      datasource.Remove(listbox.SelectedItem.ToString()) 
     ) 
    ) 
}); 

private void buttonAdd_Click(object sender, EventArgs e) 
{ 
    datasource.Add(textBox.Text); 
}