I haven't found a solution yet related to this problem. I just to disable other tabpages in my Winforms TabControl when a certain tabpage is open. So not hiding them but disable the function to open them when one clicks a tab page. It just should be displayed grey. Is this possible? I've read something about a "Selected" event but don't know how to use that.
You can use the Selecting event:
Create a class level variable:
int lockedPage = -1;
If it is set to the index of a TabPage you can select it but you can't leave it, i.e. you can't select any other page.
private void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
if (lockedPage >= 0 && e.TabPageIndex != lockedPage) e.Cancel = true;
}
If you set lockedPage = 0; you prevent the user from leaving the 1st page etc..
To re-enable the selection of other pages set it to -1
Related
I have a problem with DateTimePicker,
I put 3 DateTimePicker on tab control one for each tabitem.
Now i set time by
dateTimePicker1.Text="1:00";
dateTimePicker2.Text="2:00";
dateTimePicker3.Text="3:00";
In the first tab the DateTimePicker work fine by
MessageBox.Show(dateTimePicker1.Text); //Show "01:00"
but when i want to read dateTimePicker2.Text show me empty
but when i clicked on second tab thats work fine and show me "02:00"
whats my problem?
U gonne have to preload your tabs as the controls on it are not initiated yet.
Something like this will work
private void Form1_Load(object sender, EventArgs e)
{
// Preload tabs
tabControl1.SelectedTab = tabPage3;
tabControl1.SelectedTab = tabPage2;
// Select tab 1
tabControl1.SelectedTab = tabPage1;
// Set values
dateTimePicker1.Text = "1:00";
dateTimePicker2.Text = "2:00";
dateTimePicker2.Text = "3:00";
}
Even better u can use tabPage.show() for each tab u want to preload.
// Preload tabs
tabPage3.Show();
tabPage2.Show();
// Select tab 1
tabPage1.Show();
I would look at this page on Object Lifetime Events, specifically the Loaded section. I believe since the DatePicker is on the second tab that until it is visible and loaded it will not have the correct value.
http://msdn.microsoft.com/en-us/library/ms754221.aspx
All,I knew we can set a column editable for a DataGridView.
And when finish editing the cell. the CellEndEdit event would be triggered.
But I just want to know why didn't end the edit of cell when I click the blank area of DataGridView. And click the area out of DataGridView doesn't trigger it too. only clicking the other cells could make it happen. It really doesn't make sense. Could anyone know why ? and How to make it ? It try to use the Click event of the DataGridView, But When I click the cell, It also trigger the DataGridView_click event.
private void dgvList_Click(object sender, EventArgs e)
{
dgvFileList.EndEdit();
}
Try using the HitTest function in the MouseDown event of the grid:
void dgvFileList_MouseDown(object sender, MouseEventArgs e) {
DataGridView.HitTestInfo hit = dgvFileList.HitTest(e.X, e.Y);
if (hit.RowIndex < 0 | hit.ColumnIndex < 0) {
dgvFileList.EndEdit();
}
}
Clicking outside the DataGridView control would require hitting a focusable control.
Before BeginEdit. Set a variable to identify if current state is edit mode.
bBeginEdit = true;
dgvFileList.BeginEdit(false);
In the Form_Click event
if (bBeginEdit)
{
dgvFileList.EndEdit();
bBeginEdit = false;
}
Thanks,
Joe
CellEndEdit() causes the event to be fired only if the cell was in edit mode (see Joe.wang's response). You can simply preceed CellEndEdit() with CellBeginEdit() to enter Edit mode (code from CellContentClick-handler, PickNewFont() is a wrapper for the FontDialog):
[...]
else if (String.Compare(rowName, "Font name") == 0) // user clicks on Font-row
{
dgvConfigSettings.BeginEdit(true);
Font newFont = PickNewFont(fontName, fontSize, fontStyle);
dgvConfigSettings.CurrentCell.Tag = newFont; // a bit dirty.... but that way we can pick-up the font in the panel-handler more easily
dgvConfigSettings.CurrentCell.Value = newFont.Name.ToString();
dgvConfigSettings.EndEdit();
}
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;
}
}
Currently in my application it is impossible to deselect a textbox. The only way is to select another textbox. My users and I agree that clicking anywhere else on the form should deselect the current textbox. I tried overriding the MouseDown on many controls and having the focus set to a random label but it doesn't work for some controls like the MenuStrip or scrollbars. Any ideas?
Assuming you have no other controls on your forum, try adding a Panel control that can receive focus.
Set the TabIndex on the Panel control to something less than your TextBox or NumericUpDown control has.
Now, when your main form receives focus, the Panel should receive the focus instead of the TextBox area.
I had a similar issue recently. My interface is very complex with lots of panels and tab pages, so none of the simpler answers I found had worked.
My solution was to programatically add a mouse click handler to every non-focusable control in my form, which would try to focus any labels on the form. Focusing a specific label wouldn't work when on a different tab page, so I ended up looping through and focusing all labels.
Code to accomplish is as follows:
private void HookControl(Control controlToHook)
{
// Add any extra "unfocusable" control types as needed
if (controlToHook.GetType() == typeof(Panel)
|| controlToHook.GetType() == typeof(GroupBox)
|| controlToHook.GetType() == typeof(Label)
|| controlToHook.GetType() == typeof(TableLayoutPanel)
|| controlToHook.GetType() == typeof(FlowLayoutPanel)
|| controlToHook.GetType() == typeof(TabControl)
|| controlToHook.GetType() == typeof(TabPage)
|| controlToHook.GetType() == typeof(PictureBox))
{
controlToHook.MouseClick += AllControlsMouseClick;
}
foreach (Control ctl in controlToHook.Controls)
{
HookControl(ctl);
}
}
void AllControlsMouseClick(object sender, MouseEventArgs e)
{
FocusLabels(this);
}
private void FocusLabels(Control control)
{
if (control.GetType() == typeof(Label))
{
control.Focus();
}
foreach (Control ctl in control.Controls)
{
FocusLabels(ctl);
}
}
And then add this to your Form_Load event:
HookControl(this);
Since you probably have a label, or any other control on your winform, I would go with the solution recommended here and just give the focus to a label when the Form gets clicked.
Worst case, you can even add a label situated at the -100, -100 position, set him as the first in the tab order and Focus() it on form click.
I have some kind of "workaround" for you. Just but another control (that can get the focus) in the background. I tested this for a GridView (which will paint your control grey) - but you should be able to do it with a custom control in the color you want or just set the backgroundcolor of the gridview (doh).
This way everytime the user clicks the background this backgroundcontrol will get the focus.
This is generic answer: To deselect TextBoxes when user clicks anywhere else on the form, first make controls to lose focus. For this subscribe to Click Event of the form:
private void Form1_Click(object sender, EventArgs e)
{
this.ActiveControl = null;
}
Next subscribe your TextBoxes to Focus Leave event and set SelectionLength to 0 (to deselect text, somehow it is not deselected although textbox does not show selection when loses focus):
private void textBoxes_Leave(object sender, EventArgs e)
{
TextBox txbox = sender as TextBox;
txbox.SelectionLength = 0;
}
If you have your TexBoxes nested in custom user control, you have to add events within that user control in a similar manner. Hope that helps to anyone else.
I have a combobox with four items that correspond to tabs in a tabcontrol. When the user selects an item from the combobox (by left clicking and left clicking again to select an item) the corresponding tabpage in the tabcontrol is selected. The tabpage is set to autoscroll but when the tabpage is selected in this way mousewheel scrolling does not work. (If I click a control inside that tabpage manually I can then mousewheel scroll..)
If the user mousewheels to select an item from the same combobox (and successfully passes control to the corresponding tabpage) mousewheel scrolling works fine on that tabpage and I cant figure out why.
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
switch (comboBox1.SelectedIndex)
{
case 0:
tabControl1.SelectedTab = tabPage3;
tabPage3.Focus();
break;
}
...
}
I can't get a repro of this problem. Something that might help is to set the focus to the first control of the page instead, just like what happens when you fix the problem by clicking a control. And to do so later, after the combobox event is completed. Use this:
private void setFocusToPage(TabPage page) {
var ctl = page.Controls.Count > 0 ? page.Controls[0] : page;
this.BeginInvoke((MethodInvoker)delegate { ctl.Focus(); });
}
Call setFocusToPage instead of the Focus() method in your SelectedIndexChanged event handler.