I have seem some questions similar to this but not exactly this so. Im trying to make multiple selection in a DataGridView with only one column and multiple rows. I want the capability to select and unselect with normal click (without pressing Ctrl) and that the selection remains until I click again. I got
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.Rows.Add();
dataGridView1.Rows.Add();
dataGridView1.Rows.Add();
}
DataGridView1.MultipleSelect = true;
DataGridView1.SelectMode = GridViewSelectMode.SelectCells;
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
//handle the keep select/unselect group
}
but how do I set up the condition of not using Ctrl key to keep the selection? Thanks
You can select the cells yourself by tweaking a bit the color schemes of the grid and store/remove them in/from a list when they are clicked:
public partial class Form1 : Form
{
/// <summary>
/// Currently selected cells.
/// </summary>
private List<DataGridViewCell> _selectedCells = new List<DataGridViewCell>();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
/* Just for test
dataGridView1.Columns.Add("A", "ColA");
dataGridView1.Columns.Add("B", "ColB");
dataGridView1.Columns.Add("C", "ColC");
dataGridView1.Columns.Add("D", "ColD");
dataGridView1.Rows.Add("A1","B1","C1","D1");
dataGridView1.Rows.Add("A2", "B2", "C2", "D2");
dataGridView1.Rows.Add("A3", "B3", "C3", "D3");
dataGridView1.Rows.Add("A4", "B4", "C4", "D4");
dataGridView1.Rows.Add("A5", "B5", "C5", "D5");
dataGridView1.Rows.Add("A6", "B6", "C6", "D6");
*/
dataGridView1.MultiSelect = false;
dataGridView1.SelectionMode = DataGridViewSelectionMode.CellSelect;
dataGridView1.EditMode = DataGridViewEditMode.EditProgrammatically;
}
private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e)
{
// Edited and added this line to avoid problems when clicking on the header.
if (e.RowIndex < 0 || e.ColumnIndex < 0) return;
// Clears all the selected cells.
dataGridView1.ClearSelection();
if (_selectedCells.Contains(dataGridView1[e.ColumnIndex, e.RowIndex]))
{
_selectedCells.Remove(dataGridView1[e.ColumnIndex, e.RowIndex]);
dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = dataGridView1.DefaultCellStyle.BackColor;
}
else
{
_selectedCells.Add(dataGridView1[e.ColumnIndex, e.RowIndex]);
dataGridView1[e.ColumnIndex, e.RowIndex].Style.BackColor = dataGridView1.DefaultCellStyle.SelectionBackColor;
}
}
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
dataGridView1.ClearSelection();
}
private void dataGridView1_DoubleClick(object sender, EventArgs e)
{
dataGridView1.BeginEdit(true);
}
}
Related
my problem is that i'm trying to have a textbox display the number of times that I have clicked on the screen. I'm having the issue of not being able to take the textbox's text and convert it to a int. Thanks!
{
public partial class Form1 : Form
{
Random rand = new Random();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
button1.Location = new Point(rand.Next(0, 750), rand.Next(0, 750));
}
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Right)
{
int mouseclick = 0;
textBox1.Text = Int32.Parse(mouseclick);
}
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
Try the following changes:
{
public partial class Form1 : Form
{
Random rand = new Random();
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
button1.Location = new Point(rand.Next(0, 750), rand.Next(0, 750));
}
int mouseclick = 0;
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Right)
{
mouseclick++;
}
textBox1.Text = mouseclick.ToString();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
}
}
}
I have moved mouseclick out of the event so that it can maintain its value and i am only incrementing mouseclick if the user clicks with the left mouse button.
The textbox datatype is a string, but its assignment is a number being parsed as a number. Perhaps the following example would be helpful.
string mouseclick = "0";
int intMouseClick = Int32.Parse(mouseclick);
textBox1.Text = intMouseClick.ToString();
You tried to convert an int into string bei using Int32.Parse(...).
But this function does the reverse conversion. It converts a string to an int.
First off, you are telling the program to set mouseclicks to 0 every single time it is clicked. You might instead want the code to read:
if (e.Button != MouseButtons.Right)
{
int mouseclick = mouseclick + 1;
textBox1.Text = Int32.Parse(mouseclick);
}
or move the int out of the if statement and just do mouseclick++;
On top of that, if you are trying to set the text boxes text, you can do it much easier by just doing this:
textBox1.Text = mouseclick.ToString();
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;
}
I want to disable multiselection in CheckedListBox. I tried
checkedListBoxWersje.SelectionMode = SelectionMode.One
but I still can check multiple items. So I want to unselect last checked item. Is it possible?
Have you considered using a GroupBox with RadioButtons?
If you really want to go with a CheckedListBox consider the following which allows only one item checked at a time.
namespace CheckListBoxSimple_C_Sharp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
checkedListBox1.ItemCheck += checkedListBox1_ItemCheck;
}
private const int maxNumberOfCheckedItems = 1;
void checkedListBox1_ItemCheck(object sender, ItemCheckEventArgs e)
{
CheckedListBox items = (CheckedListBox)sender;
if (items.CheckedItems.Count > (maxNumberOfCheckedItems - 1))
{
e.NewValue = CheckState.Unchecked;
}
}
private void Form1_Load(object sender, EventArgs e)
{
checkedListBox1.Items.AddRange(new string[] { "John", "Paul", "George", "Ringo" });
checkedListBox1.SetItemChecked(1, false);
checkedListBox1.SetItemChecked(3, false);
}
}
}
This is the code that works.
if(e.NewValue.Equals(CheckState.Checked))
for (int i = 0; i < checkedListBox1.Items.Count; ++i)
if (i != e.Index)
checkedListBox1.SetItemChecked(i, false);
I have been using code that others online have supplied but for some reason it won't let me drag items from the datagridview to the textbox. I highlight a row in the dataGridView and try to drag it to the textbox but nothing happens. I have also enabled the drop property for the textBox but still no difference. Here's the code that I am using:
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
DataGridView.HitTestInfo info = dataGridView1.HitTest(e.X, e.Y);
if (info.RowIndex >= 0)
{
if (info.RowIndex >= 0 && info.ColumnIndex >= 0)
{
string text = (String)
dataGridView1.Rows[info.RowIndex].Cells[info.ColumnIndex].Value;
if (text != null)
dataGridView1.DoDragDrop(text, DragDropEffects.Copy);
}
}
}
}
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
{
textBox1.Text = (System.String)e.Data.GetData(typeof(System.String));
}
}
private void textBox1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
Here is a small sample that i have done to give you an idea on how to do this... works perfectly for me. I used WinForms here. If WPF, there may be some more events you will need to register to in order for the drag+drop to register...
Note that you will want to add more code here and there to perform what you really want to do when you drag an item from one control to the other.
public partial class Form1 : Form
{
private Rectangle dragBoxFromMouseDown;
private int rowIndexFromMouseDown;
private int rowIndexOfItemUnderMouseToDrop;
private DataGridViewRow draggedrow;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
List<StringValue> Items = new List<StringValue>() { new StringValue("1"), new StringValue("2"), new StringValue("3"), new StringValue("4"), new StringValue("5"), new StringValue("6") };
this.dataGridView1.DataSource = Items;
}
private void dataGridView1_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button & MouseButtons.Left) == MouseButtons.Left)
{
// If the mouse moves outside the rectangle, start the drag.
if (dragBoxFromMouseDown != Rectangle.Empty &&
!dragBoxFromMouseDown.Contains(e.X, e.Y))
{
// Proceed with the drag and drop, passing in the list item.
DragDropEffects dropEffect = dataGridView1.DoDragDrop(
dataGridView1.Rows[rowIndexFromMouseDown],
DragDropEffects.Move);
}
}
}
private void dataGridView1_MouseDown(object sender, MouseEventArgs e)
{
// Get the index of the item the mouse is below.
rowIndexFromMouseDown = dataGridView1.HitTest(e.X, e.Y).RowIndex;
if (rowIndexFromMouseDown != -1)
{
// Remember the point where the mouse down occurred.
// The DragSize indicates the size that the mouse can move
// before a drag event should be started.
Size dragSize = SystemInformation.DragSize;
// Create a rectangle using the DragSize, with the mouse position being
// at the center of the rectangle.
dragBoxFromMouseDown = new Rectangle(new Point(e.X - (dragSize.Width / 2),
e.Y - (dragSize.Height / 2)),
dragSize);
this.draggedrow = this.dataGridView1.CurrentRow;
}
else
// Reset the rectangle if the mouse is not over an item in the ListBox.
dragBoxFromMouseDown = Rectangle.Empty;
}
private void dataGridView1_DragOver(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void textBox1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Move;
}
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
this.textBox1.Text = (string)this.draggedrow.Cells["Value"].Value;
}
}
public class StringValue
{
public StringValue(string s)
{
_value = s;
}
public string Value { get { return _value; } set { _value = value; } }
string _value;
}
can't you use DataGridViewCellMouseEventArgs e instead of hittest for getting row index in dataGridView1_CellMouseDown. below is your code modified hope this helps
private void dataGridView1_CellMouseDown(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (e.RowIndex >= 0)
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
string text = (String)
dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
if (text != null)
dataGridView1.DoDragDrop(text, DragDropEffects.Copy);
}
}
}
}
private void textBox1_DragDrop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(System.String)))
{
textBox1.Text = (System.String)e.Data.GetData(typeof(System.String));
}
}
private void textBox1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
I have added this code to my forum:
private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ContextMenu a = new ContextMenu();
a.MenuItems.Add(new MenuItem("Google"));
a.MenuItems.Add(new MenuItem("Yahoo"));
int currentMouseOverRow = dataGridView1.HitTest(e.X, e.Y).RowIndex;
if (currentMouseOverRow >= 0)
{
a.MenuItems.Add(new MenuItem(string.Format("", currentMouseOverRow.ToString())));
}
a.Show(dataGridView1, new Point(e.X, e.Y));
}
}
private void dataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
{
currentMouseOverRow = e.RowIndex;
}
private void dataGridView1_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
{
currentMouseOverRow = -1;
}
But how do I add the function to the context menu option?
For google,
Process.Start("https://www.google.com");
For yahoo,
Process.Start("https://www.yahoo.com");
etc.
Why not add your ContextMenu right when your Form loads rather than every time that the user right click your DataGridView which means that you have to add the Context Menu every time the user rights click your DatGridView.
Secondly, instead of ContextMenu make a ContextMenuStrip instead which more at home with DataGridView. So, your code would look like:
ContextMenuStrip a = new ContextMenuStrip();
public Form1()
{
InitializeComponent();
this.Load += new EventHandler(Form1_Load);
}
void Form1_Load(object sender, EventArgs e)
{
Image img = null;
a.Items.Add("Google", img, new System.EventHandler(ContextMenuClick));
a.Items.Add("Yahoo", img, new System.EventHandler(ContextMenuClick));
dataGridView1.ContextMenuStrip = a;
}
Then your EventHandler would look like this:
private void ContextMenuClick(Object sender, System.EventArgs e)
{
switch (sender.ToString().Trim())
{
case "Google":
Process.Start("https://www.google.com");
break;
case "Yahoo":
Process.Start("https://www.yahoo.com");
break;
}
}
And your DataGridView Mouse Click handler would look this:
void dataGridView1_MouseClick(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
int currentMouseOverRow = dataGridView1.HitTest(e.X, e.Y).RowIndex;
if (currentMouseOverRow >= 0)
{
a.Items.Add(string.Format("", currentMouseOverRow.ToString()));
}
a.Show(dataGridView1, new Point(e.X, e.Y));
}
}
You have to use ClickEvent for your menu items:
//menu items constructor
a.MenuItems.Add(new MenuItem("Google", new System.EventHandler(this.MenuItemClick)));
a.MenuItems.Add(new MenuItem("Yahoo", new System.EventHandler(this.MenuItemClick)));
private void MenuItemClick(Object sender, System.EventArgs e)
{
var m = (MenuItem)sender;
if (m.Text == "Google")
{
Process.Start("https://www.google.com");
}
}