Disabling editing in DataGridView - c#

I'm using Visual Studio 2012. I want to disable the editing on the DataGridView, it seems to work when I used this code:
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
dataGridView1.ReadOnly = true;
}
But when I get back on the menu form then go back to the form where the DataGridView is, it can now be edit. I only define
dataGridView1.ReadOnly = true;
to this form. And I don't know whats the problem. Can someone help? Thanks.
Here's my code on the button going to the menu
Menu menu = new Menu();
this.Hide();
menu.ShowDialog();
and my button going back to the DataGrid:
FrmList frmlist = new FrmList();
frmlist.Show();
this.Hide();

Why don't you try setting the ReadOnly property to True in the Properties window of the DataGridView?
Edit:
Double click on the form and in the design window, select the DataGridView and open the Properties tab. Scroll down through the properties and you will see the ReadOnly option. Change it's value to True.
You were setting the ReadOnly property in the CellContentClick event which will be executed only when user clicks on the grid cells. So, when you create a new object of the form like this,
FrmList frmlist = new FrmList();
it will just create a new instance of the form with the Properties set in the designer. Since the ReadOnly property is set to false by default and the code you wrote to set it to true has not executed, the DataGridView will be editable.

Ref:
DataGridView read only cells
this.dgridvwMain.Rows[index].Cells["colName"].ReadOnly = true;

add this to your code:
dataGridView1.ReadOnly = true;
or you can change Read Only property in designer mode.

Check if the form is reinitialized on navigation. You can set a breakpoint in the constructor. This depends on your navigation service, or how ever it is implemented. In this case you can set the ReadOnly Flag to the last value on initialization or implement it as singleton.

Make the the entire DataGridView read only.
For more information visit MSDN
private void Button8_Click(object sender, System.EventArgs e)
{
foreach (DataGridViewBand band in dataGridView.Columns)
{
band.ReadOnly = true;
}
}

Related

C# WinForms ListBox changes selection to first item

I got a problem with a ListBox in a WinForm application. I have two ListBoxes inside of a tab control and depending on the selection in the first one (lb1), the DataSource of the second one (lb2) changes. This is done in the SelectedValueChanged Event.
private void listBox_ControlUnits_SelectedValueChanged(object sender, EventArgs e)
{
ControlUnit unit = (sender as ListBox).SelectedItem as ControlUnit;
textBox_ProjectNameTab.Text = unit.ProjectName;
listBox_ControlCircuits.DataSource = null;
listBox_ControlCircuits.DataSource = unit.ControlCircuits;
}
lb1 is filled with a DataSource, too.
Now if I select a value in lb1 the selection automatically jumps back to the first item and I can not figure out why. is this some kind of UI update problem?
Even without the SelectedValueChanged event and the connection to the second listbox the issue occures.
Short gif of the problem, sorry for the blurriness
If I select one item more than once it works somehow (as seen in the gif).
Edit:
I found the problem but I do not quite understand what happens.
I have another listBox on another tab of my tab control. This listBox has the same DataSource as lb1. This seems to cause this behavior.
I finally found the problem:
I did not know that if I use the same DataSource for two ListBoxes they share the BindingContext per default.
I created a new BindingContext for the second ListBox and now the selection does no longer change.
listBox_allGroups.DataSource = null;
listBox_allGroups.DataSource = x.y;
listBox_allGroups.DisplayMember = "Name";
listBox_ControlUnits.DataSource = null;
listBox_ControlUnits.DataSource = x.y;
listBox_ControlUnits.DisplayMember = "Name";
listBox_ControlUnits.BindingContext = new BindingContext();
You can use a variable to hold the selected item
object _selecteditem=null;
and check it in ListBox click event.
prive void ListBox1_Click(object sender,EventArgs e)
{
if(ListBox1.SelectItem == _selecteditem) return;
// do ...
}

How to activate combobox on first click (Datagridview)

In winforms, you need to click the combobox twice to properly activate it - the first time to focus it, the second time to actually get the dropdown list.
How do I change this behavior so that it activates on the very first click?
This is for DATAGRIDVIEW combobox.
I realize this is an old question, but I figured I would give my solution to anyone out there that may need to be able to do this.
While I couldn't find any answers to do exactly this... I did find an answer to a different question that helped me.
This is my solution:
private void datagridview_CellEnter(object sender, DataGridViewCellEventArgs e)
{
bool validClick = (e.RowIndex != -1 && e.ColumnIndex != -1); //Make sure the clicked row/column is valid.
var datagridview = sender as DataGridView;
// Check to make sure the cell clicked is the cell containing the combobox
if(datagridview.Columns[e.ColumnIndex] is DataGridViewComboBoxColumn && validClick)
{
datagridview.BeginEdit(true);
((ComboBox)datagridview.EditingControl).DroppedDown = true;
}
}
private void datagridview_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
datagridview.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
The above code must be tied into the CellEnter event of the datagridview.
I hope this helps!
edit: Added a column index check to prevent crashing when the entire row is selected.
Thanks, Up All Night for the above edit
edit2: Code is now to be tied to the CellEnter rather than the CellClick event.
Thanks, HaraldDutch for the above edit
edit3: Any changes will committed immediately, this will save you from clicking in another cell in order to update the current combobox cell.
Set the following on your DataGridView:
EditMode = EditOnEnter
This is probably the easiest solution and has been the workaround for many users here on SO when this question gets asked.
EDIT :
Per here do the following:
Set the Editmode:
EditMode = EditOnKeystrokeOrF2
Modify the EditingControlShowing event on the datagridview:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox ctl = e.Control as ComboBox;
ctl.Enter -= new EventHandler(ctl_Enter);
ctl.Enter += new EventHandler(ctl_Enter);
}
void ctl_Enter(object sender, EventArgs e)
{
(sender as ComboBox).DroppedDown = true;
}
This will get you your desired results. Let me know if that doesn't do it.
I changed only the EditMode property of the datagridview to EditOnEnter and it's working perfectly.
EditMode = EditOnEnter
If you set the entire grid to EditOnEnter, you can get some pretty funky activity when you are on a text column. Here's my solution, which should be self explanatory. If you did not know the column names, you could just check the cell type on mousemove.
Private Sub GridView_CellMouseMove(sender As Object, e As System.Windows.Forms.DataGridViewCellMouseEventArgs) Handles GridView.CellMouseMove
Select Case GridView.Columns(e.ColumnIndex).Name
Case "Ad_Edit", "Size_Caption", "Demo_Code"
GridView.EditMode = DataGridViewEditMode.EditOnEnter
Case Else
GridView.EditMode = DataGridViewEditMode.EditOnKeystrokeOrF2
End Select
End Sub
Set the DropDownStyle property of your combo box to DropDownList...
Perhaps old.. But make sure to set ReadOnly property to false, else the cell wont enter editmode and therefore the EditingControl returns null and casting DroppedDown = true will cast a NullReferencException.

Disable gridview cell editing with RepositoryItemTextEdit

I'm trying to disable editing for specific gridview cells.
I'm using a RepositoryItemTextEdit with the following properites:
repositoryItemTextEdit.AllowFocused = false;
m_repositoryItemTextEdit.ReadOnly = true;
However i can still click the cell and the edit cursor is present even if i can't change the value.
Is there a way o get rid of the text cursor?
Thank you
I got a same problem the cell and the edit cursor is present while after disabled.
And i got the solution.
private void tree_ShowingEditor(object sender, CancelEventArgs e)
{
Nodes.PromptNode promptNode = tree.FocusedNode as Nodes.PromptNode;
if (tree.FocusedColumn == valueColumn && promptNode.PromptResult.ValueType.MyValueType == ValueType.ValueTypeOptions.Calculated)
{
e.Cancel = true;
}
}
Using ShowingEditor event to cancelled this.
Basically, you have to handle the ShownEditor Event of the GridView. In there, you test the focused row and column and if the cell should be readonly, you do:
grdView.ActiveEditor.Properties.ReadOnly = True
To make things nice and understanable for the user, you can also handle the CustomDrawCell Event, and set the background color (e.Appearance) to the color used for your readonly controls.
This might be somewhat besides the point, since it doesn't get rid of the cursor; but I don't see what that would be useful.

Programatically change focus for TextBox in C#

I have a class derived from TextBox in C#. I override OnClick method to show a file open dialog. Is it possible to lose focus after that? I don't want the user to be able to edit the text because at a moment the file name might be invalid. I tried to set ReadOnly = true, but one can change the text after selecting the file.
EDIT:
I added the relevant code for this. As it is now the focus will be set to next control from my Form.
class Property : TextBox
class FileSelectTextBox : Property
{
protected override void OnClick(EventArgs e)
{
OpenFileDialog dialog = new OpenFileDialog();
Enabled = false;
if (dialog.ShowDialog(this) == DialogResult.OK)
{
Text = dialog.FileName;
}
Enabled = true;
}
}
You have several options here:
Make the textbox ReadOnly. The textbox will still fire OnClick events but the text won't be editable by the user.
Disable the textbox at the end of your click event -- the disadvantage is that the click event won't fire a second time (which means the user won't be able to change their mind and pick a new file).
Simply set the focus somewhere else at the end of the click event. (someOtherTextBox.Focus())
Edit: Once last suggestion: you may want your file popup to happen in FocusGained rather than OnClick, that way the dialog will still pop up if the user tabs into the control. Of course it's your decision if that behavior is desired or not.
Edit 2: Ignore that last edit. It's a bad suggestion that I didn't think through. (Thanks for the heads up commenter)
set the ReadOnly = true property of the textbox (don't change it at any point of time) and it should work lonely..
and rest of the code goes like this..
protected override void OnClick(EventArgs e)
OpenFileDialog dialog = new OpenFileDialog();
//user can still change/edit some non-existing file/path and click OK, so set the followings
dialog.CheckFileExists = true;
dialog.CheckPathExists = true;
if (dialog.ShowDialog(this) == DialogResult.OK)
{
Text= dialog.FileName;
}
}

C# - Can I Data Bind between a value and an expression?

I have a List and a Button. When the Lists Count == 0, I would like the button Visibility to = false.
How do I do this using Data Binding?
Thanks in advance,
Added
I have asked this so that I can try to avoid checking the Count on the list in code every time I add or remove an item to or from the list. But if there is no solution then I will continue to do it that way.
Create a DTO (Data Transfer Object) that exposes all your data that you intend to bind to UI elements. Create a property in the DTO (with an appropriate name):
public bool ButtonVisible
{
get { return myListCount != 0; }
}
Add a BindingSource to your form and set it's DataSource to your DTO type.
Click on the Button, goto Properties. Expand the DataBindings node, and click Advanced.
Scroll down the list in the left hand pane, and select Visible. Set it's binding to your property exposed vis the BindingSource..
The General Answer
Write an event handler and register it with your list-control's bindings object
A Specific Example
class MyForm : Form {
protected Button myButton;
BindingSource myBindingSource;
DataGridView dgv;
public MyForm(List someList) {
myBindingSource = new BindingSource();
dgv = new DataGridView();
this.myButton = new Button();
this.Controls.Add(myButton);
this.Controls.Add(dgv);
myBindingSource.DataSource = someList;
dgv.DataSource = myBindingSource;
dgv.DataSource.ListChanged += new ListChangedEventHandler (ListEmptyDisableButton);
}
protected void ListEmptyDisableButton (object sender, ListChangedEventArgs e) {
this.myButton.Visible = this.dgv.RowCount <= 0 ? false : true;
}
}
PS - I'd vote down the favorite answer. A Data Transfer Object (DTO) misses the whole point and functionality of .NET Binding architechture
As the question is currently worded, it doesn't sound like it has anything to do w/ DataBind.
If we have a list -- doesn't matter whether it's populated via code or bound to a data source -- we can set the button's visibility based on the count.
e.g.
List<string> somelist = new List<string>();
somelist.Add("string1");
somelist.Add("string2");
Button1.Visible = somelist.Count > 0 ? true : false;
I think you want to be using the CurrencyManager and the BindingContext of the control.
http://www.akadia.com/services/dotnet_databinding.html#CurrencyManager

Categories