Actually, my code is "selecting hover" all the line, when i have the mouse over the cell, but, i want to change it, i want to select all the column, not the line.
Data Grid
How can i manage it?
My code is:
protected override void OnRowPostPaint(DataGridViewRowPostPaintEventArgs e)
{
base.OnRowPostPaint(e);
if (this.RectangleToScreen(e.RowBounds).Contains(MousePosition))
{
using (var b = new SolidBrush(Color.FromArgb(50, Color.Black)))
using (var p = new Pen(Color.MediumVioletRed))
{
var r = e.RowBounds;
r.Width -= 1;
r.Height -= 1;
e.Graphics.FillRectangle(b, e.RowBounds.X, e.RowBounds.Y,e.RowBounds.Width, e.RowBounds.Height);
e.Graphics.DrawRectangle(p, r);
}
}
}
I can find the same method, but to draw vertically...
Thank you
If You just want to select entire column while mouse is over any cell then You don't have to use OnRowPostPaint event , You can make the selection mode for the entire grid to select entire column instead of only one cell or entire row but to do that You need to make the SortMode for the Columns set to anything other than Automatic. here is how to do it:
private void Form1_Load(object sender, EventArgs e)
{
for (int i = 0; i < dataGridView1.ColumnCount; i++)
{
dataGridView1.Columns[i].SortMode = DataGridViewColumnSortMode.NotSortable;
}
dataGridView1.SelectionMode = DataGridViewSelectionMode.FullColumnSelect;
}
then use either OnCellMouseEnter or OnCellMouseMove events to select whole column like this:
private void OnCellMouseMove(object sender, DataGridViewCellMouseEventArgs e)
{
if (e.RowIndex == -1 || e.ColumnIndex == -1)
return;
dataGridView1.CurrentCell = dataGridView1[e.ColumnIndex, e.RowIndex];
}
refer to this Answer for more information on selecting entire column.
Maybe not exactly what you want but maybe this example can get you started:
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
Rectangle newRect = new Rectangle(e.CellBounds.X + 1,
e.CellBounds.Y + 1, e.CellBounds.Width - 4,
e.CellBounds.Height - 4);
using (
Brush gridBrush = new SolidBrush(this.dataGridView1.GridColor),
backColorBrush = new SolidBrush(e.CellStyle.BackColor))
{
using (Pen gridLinePen = new Pen(gridBrush))
{
// Erase the cell.
e.Graphics.FillRectangle(backColorBrush, e.CellBounds);
// Draw the grid lines (only the right and bottom lines;
// DataGridView takes care of the others).
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Left,
e.CellBounds.Bottom - 1, e.CellBounds.Right - 1,
e.CellBounds.Bottom - 1);
e.Graphics.DrawLine(gridLinePen, e.CellBounds.Right - 1,
e.CellBounds.Top, e.CellBounds.Right - 1,
e.CellBounds.Bottom);
// Draw the inset highlight box.
e.Graphics.DrawRectangle(Pens.Blue, newRect);
// Draw the text content of the cell, ignoring alignment.
if (e.Value != null)
{
e.Graphics.DrawString((String)e.Value, e.CellStyle.Font,
Brushes.Crimson, e.CellBounds.X + 2,
e.CellBounds.Y + 2, StringFormat.GenericDefault);
}
e.Handled = true;
}
}
}
The example comes from this page learn.microsoft.com DataGridView.OnCellPainting
This will select all the cells within the hovered column... though it's not really clear what you are asking for.
using System.Windows.Forms;
namespace DatagridViewSelectAllCells_58842788
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
for (int i = 0; i < 10; i++)
{
dataGridView1.Rows.Add($"col1_{i}", $"col2_{i}");
}
dataGridView1.CellMouseEnter += DataGridView1_CellMouseEnter;
}
private void DataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex == -1)//don't do anything if the rowheader is being hovered
{
return;
}
if (dataGridView1.SelectedCells.Count > 1 && e.ColumnIndex == dataGridView1.SelectedCells[0].ColumnIndex)//don't do anything if the column is already selected
{
return;
}
dataGridView1.ClearSelection();//clear the current selection
//select all the cells in that hovered column
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
dataGridView1[e.ColumnIndex, i].Selected = true;
}
}
}
}
here's an updated answer for just changing the color of the cells
using System.Windows.Forms;
using System.Drawing;
namespace DatagridViewSelectAllCells_58842788
{
public partial class Form1 : Form
{
static Color originalColor;
static int highlightedCol = -1;
static DataGridView dataGridView1 = new DataGridView();
public Form1()
{
InitializeComponent();
Controls.Add(dataGridView1);
dataGridView1.Dock = DockStyle.Fill;
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn());
for (int i = 0; i < 10; i++)
{
dataGridView1.Rows.Add($"col1_{i}", $"col2_{i}");
}
dataGridView1.CellMouseEnter += DataGridView1_CellMouseEnter;
dataGridView1.CellMouseLeave += DataGridView1_CellMouseLeave;
dataGridView1[1, 4].Style.BackColor = Color.DarkOliveGreen;
}
private void DataGridView1_CellMouseLeave(object sender, DataGridViewCellEventArgs e)
{
//WithCellStyle(sender, e, "Leave");
WithDefaultStyle(sender, e, "Leave");
}
private void DataGridView1_CellMouseEnter(object sender, DataGridViewCellEventArgs e)
{
//WithCellStyle(sender, e, "Enter");
WithDefaultStyle(sender, e, "Enter");
}
/*
* to handle cells that have specific style attributes
* like cell dataGridView1[1, 4]
* there would be more to this to keep track of multiple different cell styles on the Leave side of thing
* but that's up to you to handle if you have a need for it.
*/
private static void WithCellStyle(object sender, DataGridViewCellEventArgs e, string eType)
{
switch (eType)
{
case "Enter":
if (originalColor == null)
{
originalColor = ((Control)sender).BackColor;//store the color for leave event
}
highlightedCol = e.ColumnIndex;//set which column is highlighted for leave event
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
dataGridView1[highlightedCol, i].Style.BackColor = Color.Aquamarine;
}
break;
case "Leave":
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
dataGridView1[highlightedCol, i].Style.BackColor = originalColor;
}
break;
default:
break;
}
}
/*
* if you only have default styles
*/
private static void WithDefaultStyle(object sender, DataGridViewCellEventArgs e, string eType)
{
switch (eType)
{
case "Enter":
if (originalColor == null)
{
originalColor = ((Control)sender).BackColor;//store the color for leave event
}
highlightedCol = e.ColumnIndex;//set which column is highlighted for leave event
//change color of all the cells
dataGridView1.Columns[highlightedCol].DefaultCellStyle.BackColor = Color.Aquamarine;//set the new color
break;
case "Leave":
//per defaultstyle
dataGridView1.Columns[highlightedCol].DefaultCellStyle.BackColor = originalColor;
break;
default:
break;
}
}
}
}
Related
I made a control on CellEndEdit event to prevent null or empty values. When user edits a cell and clicks to next cell for example and leave that one empty, it gives error and sets CurrentCell property to the empty cell. After i edit empty cell and click TAB value moves to next cell and current cell move next to next cell. I may explained it confusingly so let me show you a it's video record. I also have CellClick event to begin editing when i click the cell.
Here is the code:
private void notTakipPaneli_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (String.IsNullOrEmpty(notTakipPaneli[e.ColumnIndex, e.RowIndex].FormattedValue.ToString()))
{
MessageBox.Show("Lütfen hücreyi boş bırakmayınız.");
notTakipPaneli.CurrentCell = notTakipPaneli[e.ColumnIndex, e.RowIndex];
notTakipPaneli.BeginEdit(true);
//for (int i = e.ColumnIndex + 1; i < notTakipPaneli.Rows[e.RowIndex].Cells.Count; i++)
// notTakipPaneli[i, e.RowIndex].Selected = false;
return;
}
if (e.ColumnIndex == (notTakipPaneli.Rows[e.RowIndex].Cells.Count) - 2)
{
double ortalama = 0;
byte vize = Convert.ToByte(notTakipPaneli.Rows[e.RowIndex].Cells[1].FormattedValue);
byte final = Convert.ToByte(notTakipPaneli.Rows[e.RowIndex].Cells[(notTakipPaneli.Rows[e.RowIndex].Cells.Count) - 2].FormattedValue);
byte araSinav = Convert.ToByte(notTakipPaneli.Rows[e.RowIndex].Cells["araSinav"].FormattedValue);
if (araSinav == 0)
ortalama = (vize * 0.4) + (final * 0.6);
else
ortalama = (vize * 0.2) + (araSinav * 0.2) + (final * 0.6);
ortalama = Math.Round(ortalama, 2, MidpointRounding.AwayFromZero);
notTakipPaneli.Rows[e.RowIndex].Cells["notOrtalamasi"].Value = ortalama;
}
}
private void veriKaydet_Click(object sender, EventArgs e)
{
for (int i = 0; i < notTakipPaneli.Rows.Count; i++)
{
for (int j = 0; j < notTakipPaneli.Columns.Count; j++)
{
if (String.IsNullOrEmpty(notTakipPaneli[j, i].FormattedValue.ToString()))
{
MessageBox.Show("Lütfen boş alan bırakmayınız",
"Not Takip Paneli",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
notTakipPaneli[j, i].Selected = true;
return;
}
}
}
}
private void yeniSatirEkle_Click(object sender, EventArgs e)
{
notTakipPaneli.Rows.Add();
}
private void notTakipPaneli_CellClick(object sender, DataGridViewCellEventArgs e)
{
notTakipPaneli.BeginEdit(true);
}
Maybe you can try to wrap that code in a BeginInvoke block.
private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
if (String.IsNullOrEmpty(dataGridView1[e.ColumnIndex, e.RowIndex].FormattedValue.ToString()))
{
MessageBox.Show("Lütfen hücreyi boş bırakmayınız.");
this.BeginInvoke(new Action(() => {
dataGridView1.CurrentCell = dataGridView1[e.ColumnIndex, e.RowIndex];
dataGridView1.BeginEdit(true);
}));
return;
}
}
I have cell name "MY_CELL"
I want to create if "MY_CELL" value is OK! then that Row color will be changed with GreenYellow.
private void gridView2_RowStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs e)
{
if (gridView2.RowCount > 0)
{
for (int i = 0; i < gridView2.DataRowCount; i++)
{
string text_sms2 = gridView2.GetRowCellValue(i, "MY_CELL").ToString();
if (text_sms2.Contains("ok"))
{
e.Appearance.BackColor = Color.GreenYellow;
}
else
{
e.Appearance.BackColor = Color.Red;
}
}
}
}
These code seems like works but all my rows color changed with "GreenYellow".
There's no need for the loop, since RowStyle event is raised for each individial row. Your code is setting apperence for each row according to the value in the last one.
Try this:
private void gridView2_RowStyle(object sender, DevExpress.XtraGrid.Views.Grid.RowStyleEventArgs e) {
if (e.RowHandle >= 0) {
e.HighPriority = true;
var text = gridView2.GetRowCellDisplayText(e.RowHandle, view.Columns["MY_CELL"]);
if(text.Contains("ok") { // mind case sensitivity!!!
e.Appearance.BackColor = Color.GreenYellow;
}
else {
e.Appearance.BackColor = Color.Red;
}
}
}
i want to implement combobox (search anywhere within list, not just first letter). i saw this here but didn't help me.
i using following code
private void cmbMenuName_TextChanged(object sender, EventArgs e)
{
DataTable dt = dtMenuOriginal;//dtMenuOriginal-Orginal data
dt.DefaultView.RowFilter = string.Format("MenuName LIKE '%{0}%'", cmbMenuName.Text);
cmbMenuName.DataSource = dt;
}
this code is only working for first character Press please tell me on which event i will call or any other way to solve this
I use this Link which is useful for auto-complete Textbox control.
My code-
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
namespace Combo_MiddleText_AutocompleteDemo
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
//don't forget to create/initialize our own autocomplete listbox
this.InitializeAutoComplete();
}
private void InitializeAutoComplete()
{
this.SuspendLayout();
//Create a new listbox that will be shown for the auto-complete
//
// _listBox
//
_listBox = new System.Windows.Forms.ListBox();
_listBox.Visible = false;
_listBox.Location = new System.Drawing.Point(0, 0);
_listBox.Name = "_listBox";
_listBox.Size = new System.Drawing.Size(120, 96);
_listBox.TabIndex = 0;
_listBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this._listBox_MouseDown);
//
// AutoCompleteTextBox - attach some events
//
cmbMenuName.KeyDown += new System.Windows.Forms.KeyEventHandler(this.cmbMenuName_KeyDown);
cmbMenuName.KeyUp += new System.Windows.Forms.KeyEventHandler(this.cmbMenuName_KeyUp);
this.ResumeLayout(false);
}
#region Variables
Hashtable hash;
private String[] _values;
private ListBox _listBox;
private bool _isAdded;
private String _formerValue = String.Empty;
#endregion Variables
private void Form1_Load(object sender, EventArgs e)
{
FillGrid(125);// Menu combobox in Quotation Menu Grid
cmbMenuName.DroppedDown = false;
}
public DataTable FillGrid(int QueryNo)
{
try
{
hash = new Hashtable();
DataTable dtReturn = new DataTable();
hash.Add("#QueryNo", QueryNo);
//dtReturn= ClsDefination.FillData()
dtReturn = ClsDefination.FillData("[usp_Transaction_QuotationMaster_Select]", hash);
if ((dtReturn != null && dtReturn.Rows.Count > 0))// || dtReturn2 != null && dtReturn2.Rows.Count > 0)
{
DataRow objRow = dtReturn.Rows[0];
if (QueryNo == 125) // Menu Name
{
cmbMenuName.DataSource = dtReturn;
cmbMenuName.DisplayMember = "MenuName";
cmbMenuName.ValueMember = "MenuID";
cmbMenuName.Text = "";
List<string> list = new List<string>();
for (int i = 0; i < dtReturn.Rows.Count; i++)
{
DataRow dr = dtReturn.Rows[i];
list.Add(dr["MenuName"].ToString());
}
_values = list.ToArray();
}
}
else
{
}
return null;
}
catch (Exception)
{
return null;
throw;
}
}
private void cmbMenuName_KeyDown(object sender, KeyEventArgs e)
{
//react the arrow up and down
switch (e.KeyCode)
{
case Keys.Down:
{
if ((_listBox.Visible) && (_listBox.SelectedIndex < _listBox.Items.Count - 1))
{
_listBox.SelectedIndex++;
}
break;
}
case Keys.Up:
{
if ((_listBox.Visible) && (_listBox.SelectedIndex > 0))
{
_listBox.SelectedIndex--;
}
break;
}
}
}
private void cmbMenuName_KeyUp(object sender, KeyEventArgs e)
{
//whenever a key is pressed, update the listbox content
UpdateListBox();
}
private void _listBox_MouseDown(object sender, MouseEventArgs e)
{
//select the item with the mouse
if (_listBox.Visible)
{
InsertWord((String)_listBox.SelectedItem);
HideListBox();
_formerValue = cmbMenuName.Text;
}
}
private void HideListBox()
{
//Hide the listbox
_listBox.Visible = false;
}
//private void btnShow_Click(object sender, EventArgs e)
//{
// //when this button is clicked,
// //we take the values from the textbox and list them into the second listbox
// lstSelectedValues.Items.Clear();
// List<String> selectedValues = SelectedValues;
// Array.ForEach(selectedValues.ToArray(),
// selectedValue => lstSelectedValues.Items.Add(selectedValue.Trim()));
//}
public List<String> SelectedValues
{
get
{
//return the list of selection
String[] result = cmbMenuName.Text.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
return new List<String>(result);
}
}
private void UpdateListBox()
{
//fill the listbox with the new filtered values
if (cmbMenuName.Text != _formerValue)
{
_formerValue = cmbMenuName.Text;
String word = GetWord();
if (word.Length > 0)
{
//case insensitive search
String[] matches = Array.FindAll(_values, x => (x.ToUpper().Contains(word.ToUpper()) && !SelectedValues.Contains(x)));
if (matches.Length > 0)
{
ShowListBox();
_listBox.Items.Clear();
Array.ForEach(matches, x => _listBox.Items.Add(x));
_listBox.SelectedIndex = 0;
_listBox.Height = 0;
//at least the same width as the textbox
_listBox.Width = cmbMenuName.Width;
// cmbMenuName.Focus();
using (Graphics graphics = _listBox.CreateGraphics())
{
for (int i = 0; i < _listBox.Items.Count; i++)
{
_listBox.Height += _listBox.GetItemHeight(i);
// it item width is larger than the current one
// set it to the new max item width
// GetItemRectangle does not work for me
// we add a little extra space by using '_'
int itemWidth = (int)graphics.MeasureString(((String)_listBox.Items[i]) + "_", _listBox.Font).Width;
_listBox.Width = (_listBox.Width < itemWidth) ? itemWidth : _listBox.Width;
}
}
}
else
{
HideListBox();
}
}
else
{
HideListBox();
}
}
}
private void ShowListBox()
{
//display the listbox just below the textbox
if (!_isAdded)
{
this.Controls.Add(_listBox);
_listBox.Left = cmbMenuName.Left;
_listBox.Top = cmbMenuName.Top + cmbMenuName.Height;
_isAdded = true;
}
_listBox.Visible = true;
}
private String GetWord()
{
//get the current word (useful when there is more than one on the textbox)
String text = cmbMenuName.Text;
int pos = cmbMenuName.SelectionStart;
int posStart = text.LastIndexOf(';', (pos < 1) ? 0 : pos - 1);
posStart = (posStart == -1) ? 0 : posStart + 1;
int posEnd = text.IndexOf(';', pos);
posEnd = (posEnd == -1) ? text.Length : posEnd;
int length = ((posEnd - posStart) < 0) ? 0 : posEnd - posStart;
return text.Substring(posStart, length);
}
private void InsertWord(String newTag)
{
//add the new selection to the textbox
String text = cmbMenuName.Text;
int pos = cmbMenuName.SelectionStart;
int posStart = text.LastIndexOf(';', (pos < 1) ? 0 : pos - 1);
posStart = (posStart == -1) ? 0 : posStart + 1;
int posEnd = text.IndexOf(';', pos);
String firstPart = text.Substring(0, posStart) + newTag;
String updatedText = firstPart + ((posEnd == -1) ? "" : text.Substring(posEnd, text.Length - posEnd));
cmbMenuName.Text = updatedText;
cmbMenuName.SelectionStart = firstPart.Length;
}
private void cmbMenuName_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if ((e.KeyCode == Keys.Tab) && (_listBox.Visible))
{
InsertWord((String)_listBox.SelectedItem);
HideListBox();
_formerValue = cmbMenuName.Text;
}
}
private void cmbMenuName_KeyDown_1(object sender, KeyEventArgs e)
{
e.Handled = true;
}
you can also refer to this link. It used some event handlers to the toolstripcombobox in c++. Toolstripcombobox is somehow similar to combobox since it is just inherited from combobox and c++ and c# in .net seems to be similar so you won't have much problem understanding the concept of the code.
I have a custom Datagrid, in that datagrid I change the way we select element.
I have some feature added to the selection, like :
When we select element, it's like the "Ctrl" key was press.
When we click on a selected row, the row become unselected.
When we do a multiple selection, all the row change the selectedValue for the one that the first row is going to have.
When we do a multiple selection (mouse down, move, then mouse up) with Right click it's reversing the selected value of the rows.
It's a DataGrid extension, so I am coding only in C#.
For doing that I added event handle on PreviewMouseDown and MouseUp of for the datagridrow.
private enum ButtonClicked {Left, Middle, Right};
private ButtonClicked m_oMouseButtonClicked;
private void PreviewMouseDownHandler(object sender, MouseButtonEventArgs e)
{
DataGridRow row = sender as DataGridRow;
if (e.LeftButton == MouseButtonState.Pressed)
{
row.IsSelected = !row.IsSelected;
m_oMouseButtonClicked = ButtonClicked.Left;
}
else if (e.RightButton == MouseButtonState.Pressed)
{
//row.IsSelected = !row.IsSelected;
m_oMouseButtonClicked = ButtonClicked.Right;
}
row.CaptureMouse();
row.MouseMove += row_MouseMove;
e.Handled = true;
}
void row_MouseMove(object sender, MouseEventArgs e)
{
Point oPosFromThis = e.GetPosition(this);
if (oPosFromThis.Y > this.ActualHeight)
{
}
else if (oPosFromThis.Y < 0)
{
}
}
void Row_MouseUp(object sender, MouseButtonEventArgs e)
{
int nStart;
int nEnd;
DataGridRow row = sender as DataGridRow;
row.ReleaseMouseCapture();
row.MouseMove -= row_MouseMove;
int nStartRowIndex = ItemContainerGenerator.IndexFromContainer(row);
Point oPosFromRow = e.MouseDevice.GetPosition(row);
int nEndRowIndex = nStartRowIndex + (int)Math.Floor(oPosFromRow.Y / row.ActualHeight);
if (nStartRowIndex < nEndRowIndex)
{
nStart = Math.Max(nStartRowIndex, 0);
nEnd = Math.Min(nEndRowIndex, Items.Count - 1);
}
else
{
nStart = Math.Max(nEndRowIndex, 0);
nEnd = Math.Min(nStartRowIndex, Items.Count - 1);
}
for (; nStart <= nEnd; ++nStart)
{
DataGridRow oTmp = ((DataGridRow)ItemContainerGenerator.ContainerFromIndex(nStart));
if (m_oMouseButtonClicked == ButtonClicked.Left)
{
oTmp.IsSelected = row.IsSelected;
}
else if (m_oMouseButtonClicked == ButtonClicked.Right)
{
oTmp.IsSelected = !oTmp.IsSelected;
}
}
e.Handled = true;
}
I give the mouse capture to my row i clicked, to be able to catch the mouseUp even if i go outside the datagrid.
But with my code, I lost a feature that i would like to have. The auto scrolling when I do a multiple selection and i go under or upper the datagrid. I know that iI will have to add MouseMove Handler to do it, but for now i am stuck cause I don't know how to do it.
I finally found a solution by try-error attempts. I added method to get the scrollviewer element, then i am starting a Timer to execute the scroll alone.
public claa AAA
{
private enum ButtonClicked {Left, Middle, Right};
private ButtonClicked m_oMouseButtonClicked;
private DispatcherTimer m_oTimer;
private double m_nScrollOffset;
private ScrollViewer m_oScrollBar;
public IcuAlertGrid()
{
this.Initialized += IcuAlertGrid_Initialized;
this.Loaded += IcuAlertGrid_Loaded;
m_oTimer = new DispatcherTimer();
m_oTimer.Tick += m_oTimer_Tick;
m_oTimer.Interval = new TimeSpan(2500000);
}
void IcuAlertGrid_Initialized(object sender, EventArgs e)
{
setStyle0(true);
//throw new NotImplementedException();
}
void IcuAlertGrid_Loaded(object sender, RoutedEventArgs e)
{
m_oScrollBar = GetScrollViewer(this);
}
void m_oTimer_Tick(object sender, EventArgs e)
{
if (m_oScrollBar != null)
{
m_oScrollBar.ScrollToVerticalOffset(m_oScrollBar.VerticalOffset + m_nScrollOffset);
}
}
private void PreviewMouseDownHandler(object sender, MouseButtonEventArgs e)
{
DataGridRow row = sender as DataGridRow;
if (e.LeftButton == MouseButtonState.Pressed)
{
row.IsSelected = !row.IsSelected;
m_oMouseButtonClicked = ButtonClicked.Left;
}
else if (e.RightButton == MouseButtonState.Pressed)
{
//row.IsSelected = !row.IsSelected;
m_oMouseButtonClicked = ButtonClicked.Right;
}
row.CaptureMouse();
row.MouseMove += row_MouseMove;
e.Handled = true;
}
private void row_MouseMove(object sender, MouseEventArgs e)
{
DataGridRow oRow = sender as DataGridRow;
Point oPosFromThis = e.GetPosition(this);
if (oPosFromThis.Y < 0)
{
m_nScrollOffset = -1.0;
m_oTimer.Start();
}
else if (this.ActualHeight < oPosFromThis.Y)
{
m_nScrollOffset = 1.0;
m_oTimer.Start();
}
else
{
m_oTimer.Stop();
}
}
private void Row_MouseUp(object sender, MouseButtonEventArgs e)
{
int nStart;
int nEnd;
m_oTimer.Stop();
DataGridRow row = sender as DataGridRow;
row.ReleaseMouseCapture();
row.MouseMove -= row_MouseMove;
int nStartRowIndex = ItemContainerGenerator.IndexFromContainer(row);
Point oPosFromRow = e.MouseDevice.GetPosition(row);
int nEndRowIndex = nStartRowIndex + (int)Math.Floor(oPosFromRow.Y / row.ActualHeight);
if (nStartRowIndex < nEndRowIndex)
{
nStart = Math.Max(nStartRowIndex, 0);
nEnd = Math.Min(nEndRowIndex, Items.Count - 1);
}
else
{
nStart = Math.Max(nEndRowIndex, 0);
nEnd = Math.Min(nStartRowIndex, Items.Count - 1);
}
for (; nStart <= nEnd; ++nStart)
{
DataGridRow oTmp = ((DataGridRow)ItemContainerGenerator.ContainerFromIndex(nStart));
if (m_oMouseButtonClicked == ButtonClicked.Left)
{
oTmp.IsSelected = row.IsSelected;
}
else if (m_oMouseButtonClicked == ButtonClicked.Right)
{
oTmp.IsSelected = !oTmp.IsSelected;
}
}
e.Handled = true;
}
private static ScrollViewer GetScrollViewer(DependencyObject p_oParent)
{
ScrollViewer child = default(ScrollViewer);
int numVisuals = VisualTreeHelper.GetChildrenCount(p_oParent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(p_oParent, i);
child = v as ScrollViewer;
if (child == null)
{
child = GetScrollViewer(v);
}
if (child != null)
{
break;
}
}
return child;
}
}
I have a Windows Forms project with a TabControl.
Does anyone know how to change the SelectedTab when you hover over it with the pointer?
You can use TabControl's MouseMove event to detect whether your mouse is present on any tab and then can select it:
private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
Rectangle mouseRect = new Rectangle(e.X, e.Y, 1, 1);
for (int i = 0; i < tabControl1.TabCount; i++)
{
if (tabControl1.GetTabRect(i).IntersectsWith(mouseRect))
{
tabControl1.SelectedIndex = i;
break;
}
}
}
Try this:
private void tabControl1_MouseMove(object sender, MouseEventArgs e)
{
for (int i = 0; i < tabControl1.TabCount; i++)
{
if (tabControl1.GetTabRect(i).Contains(e.X, e.Y))
{
tabControl1.SelectedIndex = i;
break;
}
}
}