Windows Forms method Form.ShowDialog() strange behaviour - winforms

I was trying to show a form(FormChild), with some radio buttons in, just to select, close, and get the value of the selected radio button from the calling form(FormParent). On a click event handler for a Button in FormParent, I just did:
var formChild=newFormChild();
formChild.ShowDialog(this);
All was working great until I decided to handle the CheckedChanged event of one of the RadioButtons inside FormChild:
private void SomeRadioButton_CheckedChanged(object sender, EventArgs e)
{
Close();
}
Now the formChild.ShowDialog(this); did not showed formChild and formChild immediately returns DialogResult.Cancel.
Any explanation on this?
Thanks in advance

The lowest Tab Index radiobutton will be checked by default, If this event handler is assigned to that button it will cause the situation that you are describing.
You can either change your Tab Order or create a Boolean Flag that is set in your Forms Shown EventHandler to keep it from Triggering until you check it again.
public partial class Form1 : Form
{
bool initDone;
public Form1()
{
InitializeComponent();
}
private void radioButton1_CheckedChanged(object sender, EventArgs e)
{
if (initDone)
{
if (((RadioButton)sender).Checked == true)
{
Close();
}
}
}
private void Form1_Shown(object sender, EventArgs e)
{
initDone = true;
}
}

Is there anywhere if your code that sets the value of the RadioButton? If you programmatically set the "Checked" property of the RadioButton, it will fire the event.
In your situation, the event handler contains your Form.Close() so the form never gets the chance to be visible to the user.
Note: Setting the RadioButton.Checked as "true" in the designer will not fire the event.

Related

How to change a control property from a UserControl

I have a form named Form1 and 2 UserControl named USC1,USC2. In USC1 i have a Button. Two USCs(USC1,USC2) have been added to Form 1 and the Visible attribute of USC2 is set to false. When i click the button in USC1, how do I get the USC2 to Visible (USC2.Visible = true) ?
Picture:
Change the modifier of the Button to public or expose it via a property. In the form's constructor after InitializeComponent(), subscribe to the button's click event:
public Form1()
{
InitializeComponent();
USC1.button1.Click += OnButtonClick;
}
private void OnButtonClick(object sender, EventArgs e)
{
USC2.Visible = true;
}

OnAddedToForm designer event for UserControl?

Is there an event for a UserControl that only fires the first time it is added to a form? I basically want to show a memmo on how to use the control to the user once they add the control into the form, but never show it afterwards (until they add another instance of this control).
An easy way to do that could be:
Use the event ParentChanged from Control : Control.ParentChanged Event
UserControl is an heritance of Control
In your UserControl, you could use a private field to define if the item has been already added to a parent.
This code could work for you:
public class CustomUserControl : UserControl
{
private bool _firstTimeAdded = false;
private void Init()
{
this.ParentChanged += CustomUserControl_ParentChanged;
}
private void CustomUserControl_ParentChanged(object sender, EventArgs e)
{
if (Parent is Form && !_firstTimeAdded)
{
_firstTimeAdded = true;
// Show your memmo
}
}
}

Silverlight: Closing a ChildWindow when the Overlay is clicked

If the user clicks on the overlay, I want the ChildWindow to automatically close and return the user to the main screen.
Is there a property that controls this? If not, is there a way to attach a click handler to the overlay?
Turns out you can get a reference to the overlay right after it is created. After that it is a simple matter of attaching the event handler.
private void Overlay_MouseButtonDown(object sender, MouseButtonEventArgs e)
{
this.Close();
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var overlay = (Grid)GetTemplateChild("Overlay");
overlay.MouseLeftButtonDown += Overlay_MouseButtonDown;
overlay.MouseRightButtonDown += Overlay_MouseButtonDown;
}

How to set focus on textbox when showing a child window

Upon starting up my silverlight app a child window appears to prompt the user to login. Within in the window I have a username textbox that I want to be focused so that the user can begin typing without focusing it with the mouse first.
This seems like it should work:
public partial class LoginForm : ChildWindow
{
public LoginForm()
{
InitializeComponent();
}
private void ChildWindow_Loaded(object sender, RoutedEventArgs e)
{
txtUsername.Focus();
}
}
I noticed that the Load event happens before the window is rendered which might be the problem, however I don't see an event handler for Rendered or similar.
Edit: Forgot to mention this application is running in the browser.
You need set TabIndex on txtUsername with lower value than other controls on that child window.
Try this:
public partial class LoginForm : ChildWindow
{
public LoginForm()
{
InitializeComponent();
Loaded+=LoginFormLoaded;
}
private void LoginFormLoaded(object sender, RoutedEventArgs e)
{
txtUsername.Focus();
Loaded-=LoginFormLoaded;
}
}
update:
You can also add your event on your TextBox. the textbox has a Loaded event too. If you use this event, you are sure that the TextBox is loaded.
If you are running the application in the browser make sure that the silverlight plugin has focus before calling the focus method of the control.
private void ChildWindow_Loaded(object sender, RoutedEventArgs e)
{
HtmlPage.Plugin.Focus();
txtUsername.Focus();
}
This works on most browsers except I couldn't get it to work on Safari.
Here is something I use:
public partial class LoginForm : ChildWindow
{
public LoginForm()
{
InitializeComponent();
Loaded += (s, e) =>
{
txtUsername.Focus();
};
}
}
And in XAML set your TabIndex to 1
For some reason that I do not have time to figure out, the Child Window in the Silverlight SDK opens, animates, and the focus moves to some unknown place. Most of the solutions suggested on this thread do not work for me because the control receives focus briefly (you can see the focus hit the text box) and then the focus moves to somewhere else (I am guessing that the storyboard on the ChildWindow template has something to do with that). So, I figured out this work around that is actual code that has been implemented and has been proven to work:
public NewChildWindow()
{
InitializeComponent();
this.GotFocus += NewChildWindow_GotFocus;
}
private void NewChildWindow_GotFocus(object sender, RoutedEventArgs e)
{
this.GotFocus -= NewChildWindow_GotFocus;
txtBoxToFocusOn.Focus();
}
Make your textbox TabIndex="0" and in its Loaded event do the "YourtxtBox.Focus()"

WPF. Catch last window click anywhere

Is there anyway that a class can catch the last click in the application? Something like
public class MyClickManagerClass
{
public MyClickManagerClass()
{
// subscribe to a global click event
}
private void GlobalClickEventHandler(object sender, EventArgs e)
{
// do something with the click here
}
}
Thanks for your time!
If you only care to capture mouse clicks anywhere in a given Window, simply subscribing to the MouseDown or PreviewMouseDown at the window level does the trick.
If you really want it to be global to the application (and not just to the window), you should subscribe to the InputManager.PreProcessInput or InputManager.PostProcessInput event and watch for mouse events:
public MyClickManagerClass()
{
InputManager.Current.PreProcessInput += (sender, e) =>
{
if(e.StagingItem.Input is MouseButtonEventArgs)
GlobalClickEventHandler(sender,
(MouseButtonEventArgs)e.StagingItem.Input);
}
}
Note that "sender" will always be the InputManager but you can map coordinates to other controls with MouseEventArgs.GetPosition(visual).

Resources