Frage

Ich habe eine ListBox und ich möchte ein Kontextmenü jedes Element in der Liste hinzuzufügen. Ich habe die „Lösung“ gesehen die rechte Maustaste wählen Sie einen Artikel hat, und das Kontextmenü, wenn auf weißen Raum unterdrücken, aber diese Lösung fühlt sich schmutzig.

Kennt jemand einen besseren Weg?

War es hilfreich?

Lösung

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

Andere Tipps

Nur ein wenig weiter zu erarbeiten, was Frans gesagt hat ... Auch wenn die List-Box die Context besitzt, haben Sie immer die Elemente in der Menüleiste an der Zeit anpassen können es zu öffnen. So Customizing es den Inhalt basierend auf der Mausposition innerhalb der Listbox.
Das Beispiel wählt unter den Eintrag im Listenfeld auf der rechten Maustaste basiert und passt dann ein Kontextmenü Streifen basiert auf dem Artikel der Benutzer mit rechts geklickt auf. Dies ist ein einfaches Beispiel, aber sollten Sie loslegen: ein Listenfeld zu einem Formular hinzufügen und diesen Code hinzu:

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, dass Hilfe. -Mike

Es gibt keine andere Art und Weise: das Kontextmenü wird durch das Element in der Listbox nicht im Besitz, sondern durch die Listbox selbst. Es ist ähnlich wie das TreeView-Steuerelement, das auch anstelle des treenode das Kontextmenü besitzt. Also, wenn ein Element im Listenfeld ausgewählt ist, setzen Sie das Kontextmenü des Listenfeld entsprechend dem ausgewählten Element.

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

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>

Wenn sie nur eine Frage der Aktivierung oder Kontextmenüelemente zu deaktivieren, kann es effizienter sein, nur es tun, wenn das Kontextmenü gestartet wird, anstatt jedes Mal, wenn die 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;
    }
}

dies ist am besten ...

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

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

ich so tun, das funktioniert gut und schnell für mich.

private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
    {
        if (Listbox.SelectedItem == null)
            e.Cancel = true;
    }
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top