I want to allow user to drag any item from MenuStrip to a ListBox.
I did it between to ListBoxes, but can not do it with MenuStrip.
Thanks a lot for your help.
I use WinForms, C#
For the destination ListBox I modified its property
this.listBox2.AllowDrop = true;
and created the following two events:
private void listBox2_DragOver(
object sender, System.Windows.Forms.DragEventArgs e)
{
e.Effect=DragDropEffects.All;
}
private void listBox2_DragDrop(
object sender, System.Windows.Forms.DragEventArgs e)
{
if(e.Data.GetDataPresent(DataFormats.StringFormat))
{
string str= (string)e.Data.GetData(
DataFormats.StringFormat);
listBox2.Items.Add(str);
}
}
What I need is what should be done to the source MenuStrip to allow drag items from it the ListBox, in over words how to make MenuStrip draggable.
Thanks to all for their help.
I found the solution:
The missing event is that I should add event to ToolStripMenuItem_MouseDown, I prefer to use right click instead of left click to avoid the conflict between ToolStripMenuItem_Click and the drag event, this the code:
AllowDrop = true;
private void tsmi_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
DoDragDrop(sender, System.Windows.Forms.DragDropEffects.Copy);
}
Add also this code to the ListView:
private void lvAllowDropListView_DragDrop(object sender, System.Windows.Forms.DragEventArgs e)
{
System.Windows.Forms.ToolStripMenuItem button = e.Data.GetData(typeof(System.Windows.Forms.ToolStripMenuItem))
as System.Windows.Forms.ToolStripMenuItem;
if (button != null)
{
try
{
SmallImageList = sysIcons.SmallIconsImageList;
LargeImageList = sysIcons.LargeIconsImageList;
System.Windows.Forms.ToolStripMenuItem item = e.Data.GetData(typeof(System.Windows.Forms.ToolStripMenuItem))
as System.Windows.Forms.ToolStripMenuItem;
if (item != null)
{
AddToolStripMenuItem(item.Text, item.Name);
}
}
catch { }
}
}
private void AddToolStripMenuItem(string name, string tag)
{
System.Windows.Forms.ListViewItem item = new System.Windows.Forms.ListViewItem(name);
int Index = -1;
for (int i = 0; i < Items.Count;i++ )
if(Items[i].Tag.ToString() == tag)
{
Index = i;
break;
}
if (Index == -1)
{
item.Tag = tag;
Items.Add(item);
}
}
Drag Menu Strip Item is the same like ListBox item.
Check your code...
Related
How can I make button property set to enabled=true after all my textboxes are not empty?
I'm learning programming and my apps are simple.
I know how to enable this property when one of my textboxes have text but this is not the case.
Use case is that user need to put data in both textboxes and after that will be able to click btn.
How in most simple way can I validate all form and then enable button?
There are just 2 tb:
https://i.imgur.com/JUslNWE.png
You need to create a TextBox_TextChanged event and subscribe to all text boxes.
private void TextBox_TextChanged(object sender, EventArgs e)
{
int notEmptyTextBoxCount = 0;
int textBoxCount = 0;
foreach (var item in Controls)
{
if (item is TextBox txtb)
{
textBoxCount++;
if (txtb.Text != String.Empty)
notEmptyTextBoxCount++;
}
}
if (textBoxCount == notEmptyTextBoxCount)
button.Enabled = true;
else
button.Enabled = false;
}
Thanks guys for all feedback.
I have managed to do this this way:
private void ValidateTextBoxes()
{
if (loginTextBox.Text.Length != 0 && passTextBox.Text.Length != 0)
{
generateHashBtn.Enabled = true;
}
else
{
generateHashBtn.Enabled = false;
}
}
private void TextBox1_TextChanged(object sender, EventArgs e)
{
ValidateTextBoxes();
}
private void TextBox2_TextChanged(object sender, EventArgs e)
{
ValidateTextBoxes();
}
Suppose we have a ListBox with the Custom elements and the blank panel . When you drag these items to the panel , they must build on a certain logic. For example, if there's nothing panel , the element is located in the middle. But if there is , then the new element is to stay near the element that is closest to it . As such it is possible to implement?
For example:
I modified this answer of working drag and drop implementation by adding some sorting logic. Placing an item in the middle visually can be done with CSS styling.
Assumption: "closest to it" means closest alphabetically.
public object lb_item = null;
private void listBox1_DragLeave(object sender, EventArgs e)
{
ListBox lb = sender as ListBox;
lb_item = lb.SelectedItem;
lb.Items.Remove(lb.SelectedItem);
}
private void listBox1_DragEnter(object sender, DragEventArgs e)
{
if (lb_item != null)
{
listBox1.Items.Add(lb_item);
lb_item = null;
// Here I added the logic:
// Sort all items added previously
// (thereby placing item in the middle).
listBox1.Sorted = true;
}
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
lb_item = null;
if (listBox1.Items.Count == 0)
{
return;
}
int index = listBox1.IndexFromPoint(e.X, e.Y);
string s = listBox1.Items[index].ToString();
DragDropEffects dde1 = DoDragDrop(s, DragDropEffects.All);
}
private void Form1_DragDrop(object sender, DragEventArgs e)
{
lb_item = null;
}
I'm trying select an item from list box when is right clicked and show the ContextMenuStrip to display my options available, but when I click everywhere in the control (list box) is showing the ContextMenuStrip.
This is what I have in code:
private void lbSMTPEmails_MouseDown(object sender, MouseEventArgs e)
{
int SelectedIndex = lbSMTPEmails.IndexFromPoint(e.X, e.Y);
if (SelectedIndex == -1)
lbSMTPEmails.ContextMenuStrip.Hide();
else
{
lbSMTPEmails.SelectedIndex = SelectedIndex;
lbSMTPEmails.ContextMenuStrip.Show();
}
}
do you have any idea how to solve this?
Use opening event of ContextMenuStrip
void cms_Opening(object sender, System.ComponentModel.CancelEventArgs e)
{
int SelectedIndex = lbSMTPEmails.IndexFromPoint( lbSMTPEmails.PointToClient(Cursor.Position) );
if (SelectedIndex == -1)
e.Cancel = true;
else
{
lbSMTPEmails.SelectedIndex = SelectedIndex;
}
}
I did by this way and it worked!
private void listbox_MouseDown(object sender, MouseEventArgs e)
{
ShowMenuStrip = listbox.IndexFromPoint(e.Location) >= 0; //This is a global bool variable
if (ShowMenuStrip)
listbox.SelectedIndex = listbox.IndexFromPoint(e.Location);
else
listbox.SelectedIndex = -1;
}
private void ContextMenuStrip_Opening(object sender, CancelEventArgs e)
{
e.Cancel = !ShowMenuStrip;
}
Currently using a Listbox and contextMenuStrip, after item right clicked how can the item's index be retrieved from the Listbox ?
My function:
private void contextMenuStripOption1_Click(object sender, EventArgs e)
{
if (listBoxFiles.SelectedIndex == -1)
{
return;
}
Point ptCursor = Cursor.Position;
int itemIndex = listBoxFiles.IndexFromPoint(ptCursor);
}
Delete function:
private void contextMenuStripDelete_Click(object sender, EventArgs e)
{
if (listBoxFiles.SelectedIndex == -1)
{
return;
}
listBoxFiles.Items.RemoveAt(listBoxFiles.SelectedIndex);
}
Do not assign the ContextMenuStrip to the ListBox; instead open it programmatically after you have determined the selected index
int _selectedIndex;
private void listBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right) {
_selectedIndex = listBox1.IndexFromPoint(e.Location);
if (_selectedIndex == -1) {
return;
}
contextMenuStrip1.Show(listBox1.PointToScreen(e.Location));
}
}
UPDATE:
Now you can access the index from the menu item clicks
private void contextMenuStripDelete_Click(object sender, EventArgs e)
{
listBoxFiles.Items.RemoveAt(_selectedIndex);
}
No need to recalculate the selected index and to test for -1. The context menu is not opened at all if the index is -1.
Use the container control: listBoxFiles.Items.IndexOf(listBoxFiles.SelectedItem)
I have a winform with a listbox and a treeview.
Once my listbox is filled with items, I want to drag them (multiple or single) from the listbox and drop them in a node in the treeview.
If somebody has a good example in C# that would be great.
It's been a while since I've messed with Drag/Drop so I figured I'll write a quick sample.
Basically, I have a form, with a listbox on the left, and a treeview on the right. Then I put a button on top. When the button is clicked, it just puts the date of the next ten days into the list box. It also populates the TreeView with 2 parents nodes and two child nodes. Then, you just have to handle all the subsequent drag/drop events to make it work.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.treeView1.AllowDrop = true;
this.listBox1.AllowDrop = true;
this.listBox1.MouseDown += new MouseEventHandler(listBox1_MouseDown);
this.listBox1.DragOver += new DragEventHandler(listBox1_DragOver);
this.treeView1.DragEnter += new DragEventHandler(treeView1_DragEnter);
this.treeView1.DragDrop += new DragEventHandler(treeView1_DragDrop);
}
private void button1_Click(object sender, EventArgs e)
{
this.PopulateListBox();
this.PopulateTreeView();
}
private void PopulateListBox()
{
for (int i = 0; i <= 10; i++)
{
this.listBox1.Items.Add(DateTime.Now.AddDays(i));
}
}
private void PopulateTreeView()
{
for (int i = 1; i <= 2; i++)
{
TreeNode node = new TreeNode("Node" + i);
for (int j = 1; j <= 2; j++)
{
node.Nodes.Add("SubNode" + j);
}
this.treeView1.Nodes.Add(node);
}
}
private void treeView1_DragDrop(object sender, DragEventArgs e)
{
TreeNode nodeToDropIn = this.treeView1.GetNodeAt(this.treeView1.PointToClient(new Point(e.X, e.Y)));
if (nodeToDropIn == null) { return; }
if(nodeToDropIn.Level > 0)
{
nodeToDropIn = nodeToDropIn.Parent;
}
object data = e.Data.GetData(typeof(DateTime));
if (data == null) { return; }
nodeToDropIn.Nodes.Add(data.ToString());
this.listBox1.Items.Remove(data);
}
private void listBox1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void treeView1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
this.listBox1.DoDragDrop(this.listBox1.SelectedItem, DragDropEffects.Move);
}
}
You want to use the GetItemAt(Point point) function to translate X,Y location to the listview item.
Here's quite good article about it: Drag and Drop Using C#.
To make the item being dragged visible while dragging, you need to use COM ImageList, which is well described in the following article Custom Drag-Drop Images Using ImageLists.