2008-12-18 35 views
28

Tôi có một ListBox và tôi muốn thêm một menu ngữ cảnh cho mỗi mục trong danh sách. Tôi đã nhìn thấy các "giải pháp" để có nhấp chuột phải chọn một mục và ngăn chặn menu ngữ cảnh nếu trên không gian màu trắng, nhưng giải pháp này cảm thấy bẩn.Làm cách nào để thêm menu ngữ cảnh vào ListBoxItem?

Có ai biết cách nào tốt hơn không?

+0

Có thể bạn không thiết kế nó bất kỳ cách nào khác? Tôi không thể nghĩ về bất kỳ giao diện người dùng như thế này ... Tôi sẽ không bao giờ nghĩ đến việc nhấp chuột phải vào một mục hộp danh sách. – Gishu

+0

Bạn cũng đang ở trong Winforms hay WPF? Các câu trả lời có thể thay đổi tùy theo điều đó. – Gishu

Trả lời

4

Bằng cách này menu sẽ bật lên bên cạnh chuột

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

Không có cách nào khác: menu ngữ cảnh không thuộc sở hữu của mục trong hộp danh sách mà do chính hộp danh sách. Nó tương tự như kiểm soát treeview mà cũng sở hữu menu ngữ cảnh thay vì treenode. Vì vậy, bất cứ khi nào một mục trong hộp danh sách được chọn, hãy đặt menu ngữ cảnh của hộp danh sách theo mục đã chọn.

27

Chỉ để xây dựng thêm một chút về những gì Frans đã nói ... Mặc dù ListBox sở hữu ContextMenuStrip, bạn vẫn có thể tùy chỉnh các mục trong dải menu tại thời điểm mở. Do đó, tùy chỉnh nội dung của nó dựa trên vị trí chuột trong hộp danh sách.
Ví dụ dưới đây chọn mục trong hộp danh sách dựa trên nhấp chuột phải và sau đó tùy chỉnh dải menu ngữ cảnh dựa trên mục mà người dùng đã nhấp chuột phải vào. Đây là một ví dụ đơn giản nhưng sẽ giúp bạn đi: Thêm hộp danh sách vào biểu mẫu và thêm mã này:

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())); 
    } "); 

Hy vọng trợ giúp. -Mike

+0

Rất hữu ích! Cảm ơn nhiều! – asmo

+0

Tôi gặp lỗi khi listboxContextMenu_Opening không tồn tại trong ngữ cảnh hiện tại. –

1

Nếu nó chỉ là vấn đề cho phép hoặc vô hiệu hóa các mục menu ngữ cảnh, nó có thể là hiệu quả hơn để chỉ làm điều đó khi vào menu ngữ cảnh được đưa ra chứ không phải là mỗi khi lựa chọn hộp danh sách thay đổi:

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

Trong XAML nó cho thấy như thế này:

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

này là tốt nhất ...

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

Và Dưới đây là giải pháp của tôi:

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

tôi làm như thế này, các công trình này tuyệt vời và nhanh chóng cho tôi.

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

Trong một dòng mã (hơn cho ràng buộc):

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); 
} 
Các vấn đề liên quan