Yesterday I have implemented some validating events for controls in a groupbox located on a WinForm. I have set the AutoValidate property of the form to Disabled, I have set the CausesValidation property of the controls to true and implemented the Validating event of the controls. By calling the ValidateChildren() method of the form I force that validating events are executed. This was working all fine.
But after placing this groupbox on top of a picturebox and setting the picturebox as parent of the groupbox then validating events aren't executed anymore....
Below some demo code. Form is only containing a picturebox, groupbox, textbox and button.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void textBox1_Validating(object sender, CancelEventArgs e)
{
MessageBox.Show("Validating textbox");
e.Cancel = true;
}
private void button1_Click(object sender, EventArgs e)
{
if (ValidateChildren())
MessageBox.Show("Validation not executed :-(");
else
MessageBox.Show("Validation executed :-)");
}
private void Form1_Load(object sender, EventArgs e)
{
groupBox1.Parent = pictureBox1;
}
}
The ValidateChildren() method calls ValidateChildren(ValidationConstraints.Selectable) to get the job done. That's a problem for a PictureBox, it isn't selectable. So none of its children get validated either.
Calling it with ValidationConstraints.None doesn't work either, the ability to validate child controls is implemented by ContainerControl and PictureBox doesn't derive from it. So you can't call ValidateChildren on the PictureBox either. Enumerating the controls yourself and triggering the Validating event can't work either, the PerformControlValidation() method is internal.
You'll need to re-think the idea of trying to turn the PictureBox into a ContainerControl. Most any control can resemble a picturebox, if not through the BackgroundImage property then through the Paint event.
Related
I have a parent panel in a form.
This panel will display an array of different user control which will take up the full panel dimension.
I tried to use the panel 'Click' event. However when the user control is added to the panel, it does not fire the event when click.
Due to there are many widget in each user control, it would be tedious to implement 'Click' on each widget.
Is there anyway when i click on a user control, it fires the form panel event instead?
I suggest to loop the panel's controls on the form loading:
private void MyClick(object sender, EventArgs e) {
...
}
private void MyForm_Load(object sender, EventArgs e) {
foreach (Control control in myPanel.Controls)
control.Click += MyClick;
...
}
I have an application with a Panel containing children Form objects. When I click one of the children Form it brings to front. I would like to know which one is in front now...
I've looked in event list but cant find proper event form my purpose :(
These methods doesn't work:
protected void OpenedFileForm_Enter(object sender, EventArgs e)
{
MessageBox.Show("enter");
}
protected void OpenedFileForm_Click(object sender, EventArgs e)
{
MessageBox.Show("click");
}
protected void OpenedFileForm_Activated(object sender, EventArgs e)
{
MessageBox.Show("activated");
}
protected void OpenedFileForm_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("mouse click");
}
protected void OpenedFileForm_Shown(object sender, EventArgs e)
{
MessageBox.Show("shown");
}
OpenFileDialog openFile1 = new OpenFileDialog();
openFile1.DefaultExt = "*.txt";
openFile1.Filter = "TXT Files|*.txt|RTF Files|*.rtf";
if (openFile1.ShowDialog() == System.Windows.Forms.DialogResult.OK &&
openFile1.FileName.Length > 0)
{
switch (Path.GetExtension(openFile1.FileName))
{
case ".txt":
txtForm childTXT = new txtForm();
this.childForms.Add(childTXT);
childTXT.Parent = this.mainPanel;
childTXT.richTextBox1.LoadFile(openFile1.FileName, RichTextBoxStreamType.PlainText);
childTXT.Show();
break;
}
}
Have you tried the Form.Activated Event?
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.activated(v=vs.80).aspx
Edit:
If you are in an MDI application, you might need to use MdiChildActivate instead.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.mdichildactivate.aspx
This code can only work when you set the Form.TopLevel property to false. Which makes it turn into a child control, almost indistinguishable from a UserControl.
This has many side-effects, for one there is no notion of "front" anymore. The Z-order of child controls is determined by their position in their parent's Controls collection. And it affects the events it fires, Activated and Deactivated will never fire. Furthermore, the Form class was designed to be a container control, it doesn't like taking the focus itself. Its child controls get the focus, the Form class doesn't have any use for focus. Which is why the Enter, Click and MouseClick events don't fire, they are events that require focus.
Long story short, what you are trying to do doesn't make a wholeheckofalot of sense. If it is strictly the Z-order you want to fix then write an event handler for the MouseDown event:
void OpenedFileForm_MouseDown(object sender, MouseEventArgs e) {
var frm = (Form)sender;
frm.BringToFront();
}
You could add frm.Select() to get the Enter event to fire, but only do that if the form doesn't contain any focusable controls itself. Do note that there is evidence that you don't assign the events correctly in your code. The Shown event does fire. It is also important that you set the FormBorderStyle to None, the title bar cannot indicate activation status anymore.
Ok, I got this! Thx for help everyone. You gave me a hint to think about equity of my strange MDI idea where Panel is parent for other Forms. I Removed SplitContainer containing Panel and just did standard MDI application, where Forms are MDIChildren of main Form.
childTXT.MdiParent = this;
I was on my way to create a custom Progress Bar when I hit this problem [WinForm]
**The Structure:**
-panel
-> panel
so I have panel which inside the panel, there another panel.
**The Goals:**
-I want to use my parent panel as all event handler,
while make the child panel have no event at all.
**The Problem:**
- when I press my mouse inside the child panel. the event in parent wont called.
explanation : -> I still wanted to call parent panel mouse down
even if I click on top of my child panel.
So you want the click event to fire on the parent Panel when the child panel is clicked.
I can think of 2 ways you can do this.
First way is to simply call the Click event handler method for Panel1 from inside the Panel2's Click event handler method:
private void panel1_Click(object sender, EventArgs e)
{
MessageBox.Show("Panel 1 clicked.");
}
private void panel2_Click(object sender, EventArgs e)
{
this.panel1_Click(sender, e);
}
Probably a better way would be to register both click events to the 1 handler method:
private void panel1_Click(object sender, EventArgs e)
{
MessageBox.Show("Panel 1 clicked.");
}
Then from the Form Designer or manually register the event for the second panel:
this.panel2.Click += new System.EventHandler(this.panel1_Click);
I am new to using Event Handling in C# .NET, and I am trying to understand the behavior behind some simple code that I am experimenting with. I am working with a more complicated example, but I am hoping I will get a more focused answer if I simplify the example.
I have the following code which defines a main window with a ListBox that is initialized with values, and a panel in the window. I am working with dragging the ListBox Items and dropping them in the panel. To signify that the panel is reading the DragDrop event, I am simply just changing the background color.
My problem is, it is not changing the background color when I drop the values, hence, the DragDrop is not working. I know this is a bit exaggerated, but I am trying to understand why its not working.
Here is the following code that I am using.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
//Allow Panel to accept dropped values
this.panel1.AllowDrop = true;
//Initialize ListBox with sample values
listBox1.Items.Add("First Name");
listBox1.Items.Add("Last Name");
listBox1.Items.Add("Phone");
//Setup DragDrop Event Handler - is this correct, or even needed?
this.panel1.DragDrop += new DragEventHandler(panel1_DragDrop);
}
private void listBox1_MouseDown(object sender, MouseEventArgs e)
{
ListBox box = (ListBox)sender;
String selectedValue = box.Text;
DoDragDrop(selectedValue.ToString(), DragDropEffects.Copy);
}
private void panel1_DragDrop(object sender, DragEventArgs e)
{
//Change Background color to signify value has been dropped
((Panel)sender).BackColor = Color.Black;
}
}
I realize this is an oversimplified example. If you see what I am doing wrong, then please let me know.
EDIT To give an example of why I am confused, I change this example around to put the dragged ListBox Item text into a Textbox when the DragOver event was fired, and it worked fine, but when I tried to do the same thing when they dropped the values over the textbox, I could not get it to work.
Handle the panel's DragEnter event and set e.Effects to something other than None.
Purpose is to have the opacity event trigger when the form loses focus. The form has a setting for STAY ON TOP. The visual effect would be to click on a possibly overlapping window, and yet the form when not focused on would stay on top, but in the corner slightly transparent, keeping it within easy access, but providing visibility to the stuff underneath.
I 've googled and googled, and can't figure out how to get this event to properly fire when form loses focus, and then when form gains focus back to restore opacity to 100% or the level determined elsewhere.
Tips?
// under designer.cs
//
// CollectionToolForm
//
//other code....
this.LostFocus += new System.EventHandler(goTransparent);
//method
private void goTransparent(object sender, EventArgs e)
{
if (transparentCheck.Checked == true)
{
this.Opacity = 0.50;
}
else
{
this.Opacity = 1;
}
}
It sounds as if you are looking for the Activated and Deactivate events.
Update
In response to the comment about LostFocus event, it could be of interest to clarify how it works. The LostFocus event of the Form is inherited from Control. It is raised when a controls loses focus; either because the form as such is being deactivated (focus moves to another application for instance), or because focus moves to another control within the same form.
If you hook up an event handler for the LostFocus event of a form that contains only at least one control that can receive focus, you will find that the LostFocus event of the form is raised immediately after the form is displayed. This is because focus moves from the form (which is a Control) to the first focusable control on the form.
So, the form being active and the form being focused are two separate behaviours.
You tried doing it with mouse enter/leave events?
public Form1()
{
this.MouseEnter += new System.EventHandler(this.Form1_MouseEnter);
this.MouseLeave += new System.EventHandler(this.Form1_MouseLeave);
}
private void Form1_MouseLeave(object sender, EventArgs e)
{
this.Opacity = 0.5;
}
private void Form1_MouseEnter(object sender, EventArgs e)
{
this.Opacity = 1;
}