My project has a DataGridView with 52 columns and some of columns are not visible. But I want the user to make them visible easily. So I added a button as you see on the pic below. This makes five columns visible.
But the problem when scrolling, this Button stay static on form. I want this button anchored to a specific column header. Movable with column header.
So i tried to put the DataGridView and Button contols on same panel as children. That's worked but panel scroll is not functional as much as DataGridView's scroll. For example in panel scrolling freezed columns is not working.
Is there any solution for this. I want the user to make columns visible or not visible easily like Excel. it is not necessary to use a buttons. İf there any another options, I am interested.
I'll show an example of how you can use the context menu to show and hide DataGridView columns.
Add menu to Form:
ContextMenuStrip columnMenu;
Create menu like this. Each column has one menu item with a checkbox.
Of course, you can create and fill it in manually in the designer.
private void Form1_Load(object sender, EventArgs e)
{
columnMenu = new ContextMenuStrip();
foreach (DataGridViewColumn column in dataGridView.Columns)
{
var item = new ToolStripMenuItem();
item.Text = column.Name;
item.CheckOnClick = true;
item.Checked = true;
item.Click += Item_Click;
columnMenu.Items.Add(item);
}
}
When you select a menu item, show or hide the column.
private void Item_Click(object sender, EventArgs e)
{
var item = (ToolStripMenuItem)sender;
dataGridView.Columns[item.Text].Visible = item.Checked;
}
Subscribe the DataGridView on the event:
dataGridView.ColumnHeaderMouseClick += DataGridView_ColumnHeaderMouseClick;
In this event handler, show the menu.
private void DataGridView_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
columnMenu.Show(MousePosition);
}
Related
I have two datagridviews which display two seperate stored procedures at the same time, both on the same form. I have their "SelectionMode" properties set to "FullRowSelect".
However, I want only one row to be selectable at a time between the two dgvs. So if someone selects a row on dgv A, I want the selected row in dgv B to unhighlight or deactivate. And if someone selects a row in dgv B, I'd like the highlighted row in dgv A to unselect or deactivate. Is there a way to essentially share a
private void datagridview1_SelectionChanged(object sender, EventArgs e)
between two separate datagridviews?
I'm not sure where to begin with this, so I have no code examples. Any assistance with this is appreciated. Thanks!!
When selecting in dataGridView1, call dataGridView2.ClearSelection()
You mentioned a single event handler to handle both, which you can do. And you can write some code to find all other DataGridViews besides the one you clicked, and clear their selections.
private void dataGridView_SelectionChanged(object sender, EventArgs e)
{
var s = (DataGridView)sender;
if (s.SelectedRows.Count > 0)
{
var otherDataGridViews = this.Controls.OfType<DataGridView>().Except(new[] { s });
foreach (var dgv in otherDataGridViews)
{
dgv.ClearSelection();
}
}
}
That will work if the DataGridViews are inside the same container i.e. same form, not in different Panels etc.
You must specify the same handler in the designer or designer code i.e.
//
// dataGridView1
//
...
this.dataGridView1.SelectionChanged += new System.EventHandler(this.dataGridView_SelectionChanged);
//
// dataGridView2
//
...
this.dataGridView2.SelectionChanged += new System.EventHandler(this.dataGridView_SelectionChanged);
I have a WinForms application with a dataGridView which has 26 columns and is filled with data from a database. How can I allow users to hide the columns they don't want to see and show them again later? I know how to do it programmatically, but the question is how should the user do it. Here are my bad ideas:
A list of checkboxes with each column to be clicked there - this is bad because the list would be too long and won't fit inside the form.
A checkbox over each header, but I don't know how to make these checkboxes "stick" and horizontally scroll with the headers.
Clicking on a header - this works well for hiding, but there is no way to show this column again.
So what would be the solution here?
The best solution is to hide the columns after double-clicking the header and adding hidden columns to a popup menu. The popup menu contains only the hidden columns, so it is not too long. Clicking on a popup menu item removes it from the menu and shows the column.
Code:
private void DataGridView1_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex < 0)
{
string column = dataGridView1.Columns[e.ColumnIndex].Name;
dataGridView1.Columns[column].Visible = false;
contextMenuStrip1.Items.Add(column);
}
}
private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
{
var menuText = e.ClickedItem.Text;
dataGridView1.Columns[menuText].Visible = true;
contextMenuStrip1.Items.Remove(e.ClickedItem);
}
I have grid view, and I have already disable the column auto width so I can manually set the size of column. after manually resize there's a extra blank column. and what I want is :
To disable the select row function when i click on outside of the column in Active, code and generate
Remove the extra column.
I already success fully hide the remaining column with this event or code
private void gridView1_CustomDrawColumnHeader(object sender, ColumnHeaderCustomDrawEventArgs e)
{
if (e.Column == null)
{
e.Handled = true;
}
}
The thing is I still can click on the outside of the genre, and the row selection still follow where I click
Handle the GridView.MouseDown event in the following way:
private void gridView1_MouseDown(object sender, MouseEventArgs e) {
GridView view = (GridView)sender;
var hi = view.CalcHitInfo(e.Location);
Console.WriteLine(hi.HitTest);
if (hi.InRow && !hi.InRowCell)
DXMouseEventArgs.GetMouseArgs(e).Handled = true;
}
I have a DataGrid created in XAML in a C# project. I've added a context menu to the rows. Basically when the user clicks directly on the cell it should open the relevant item in the current window, which is implemented on the SelectionChanged event.
However if the user right clicks a row it should show the the context menu without selecting the row, so that the user can select an item in the context menu to open the relevant item in a new window. So they can look at both the already selected item and the new item at once, but as the right click selects the row, the user see the newly selected item in the current window and the new window.
How can I stop the right click action to show the context menu from selecting the cell?
For my solution, I have to overwrite the following two event handlers (i.e., PreviewMouseRightButtonDown and PreviewMouseRightButtonUp). Plus, not sure why data-binding for the ItemsSource does not work, so that I have to bind it manually.
private void ResultDataGrid_PreviewMouseRightButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (sender is DataGrid dg)
{
if (this.DataContext is PipelineStepResultViewModel dataContext
&& dataContext.DatagridMenuItems != null)
{
dg.ContextMenu.ItemsSource = dataContext.DatagridMenuItems;
}
}
e.Handled = true;
}
private void ResultDataGrid_PreviewMouseRightButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (sender is DataGrid dg && dg.ContextMenu.ItemsSource != null)
{
ResultDataGrid.ContextMenu.IsOpen = true;
}
e.Handled = true;
}
i have listview and two buttons; clear and view.
the view button runs perfectly as it should be and when i click the clear button, it does clear as it should.
problem happens after click the clear button, the view button seems does not work. it does not view anything that i want.
same goes when i click the clear button first then i click the view button, it will not view anything. as if the clear button will hold of the data from visible in the listview.
can anyone help me with this?
Below is my code for the clear button.
private void clear_Click(object sender, EventArgs e)
{
listView1.Clear();
}
This is my view button.
private void view_Click(object sender, EventArgs e)
{
ListViewItem listviewitem;
for (int i = 0; i <= _server.Q.NoOfItem - 1; i++)
{
String words = _server.Q.ElementAtBuffer(i).ToString();
String[] berjaya = words.Split(new char[] { ',', '[', ']', ' ' });
listviewitem = new ListViewItem(berjaya[43]);
listviewitem.SubItems.Add(berjaya[41]);
listviewitem.SubItems.Add(berjaya[1]);
listviewitem.SubItems.Add(berjaya[45]);
this.listView1.Items.Add(listviewitem);
listView1.FullRowSelect = true;
listView1.View = View.Details;
foreach (ColumnHeader ch in this.listView1.Columns)
ch.Width = -2;
}
}
for better view, here is my interface of both situation.
the first picture shows that the output when click the view button.
the second picture shows the output when click the clear button. it still print out this way either we click the clear button first or after click the view button. it will not display the data in the listview.
i even tested without using the server like this:
XmlDocument xml = new XmlDocument();
xml.Load("C:\\Users\\HDAdmin\\Documents\\SliceEngine\\SliceEngine\\bin\\Debug\\myself.xml");
XmlNodeList xnList = xml.SelectNodes("/main/myself");
listviewitem = new ListViewItem("a");
listviewitem.SubItems.Add("b");
listviewitem.SubItems.Add("c");
listviewitem.SubItems.Add("d");
this.listView1.Items.Add(listviewitem);
listView1.FullRowSelect = true;
//show header
listView1.View = View.Details;
// Loop through and size each column header to fit the column header text.
foreach (ColumnHeader ch in this.listView1.Columns)
{
ch.Width = -2;
}
still it appears the same like before.
Depedant on the code for your View button, you must know that if you want all the items to appear again after you have cleared a ListView, you must add the items back into the Listview, like so:
listView.Items.Add("I am being added to the list");
Please do post your View button code though to ensure I am answering your question correctly.
Try using
private void clear_Click(object sender, EventArgs e)
{
listView1.Items.Clear();
}
instead of
private void clear_Click(object sender, EventArgs e)
{
listView1.Clear();
}
ListView.Clear(); method is used to remove all items as well as columns from a ListView but I guess you only want items to be removed, So you should use ListView1.Items.Clear(); instead.
Creating a ListViewItem, adding items manually to a View, accessing directly the controls : all this you should not do.
You should have a DateList Property : an ObservableCollection of your ETA/Priority/date/... object. Then in your ListView you do a binding to this property ItemSource="{Binding DateList}", don't forget to setup the DataContext in the new() or loaded() function of the Window. And then you ONLY operate on DateList in your code behind, adding or removing your data items.
If you don't do like this you will buy yourself more and more problems (like this one : see that a simple operation like clearing breaks your code...)