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
}
}
}
Related
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;
}
I have a listbox that is bound to a list of custom objects. I can get the listbox items to display correctly using the ListBox.ItemTemplate in xaml. The custom objects for the listbox are all of the same base class outlined below.
public class HomeViewMenuItem : UIElement
{
private Uri _uri;
private IRegionManager _manager;
public HomeViewMenuItem(string text, Uri uri, IRegionManager manager)
{
this.PreviewMouseDown += HomeViewMenuItem_PreviewMouseDown;
this.PreviewKeyDown += HomeViewMenuItem_PreviewKeyDown;
_manager = manager;
Text = text;
_uri = uri;
ClickCommand = new DelegateCommand(this.Click, this.CanClick);
}
void HomeViewMenuItem_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
{
e.Handled = true;
this.ClickCommand.Execute();
}
}
void HomeViewMenuItem_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
e.Handled = true;
this.ClickCommand.Execute();
}
private void Click()
{
_manager.Regions[RegionNames.MainRegion].RequestNavigate(_uri);
}
private bool CanClick()
{
return true;
}
public DelegateCommand ClickCommand { get; set; }
public string Text { get; set; }
}
The problem I am having is the HomeViewMenuItem_PreviewKeyDown method is not getting called. I believe this is because the method is getting called on the ListBoxItem itself first and getting handled there. I was able to verify this by obtaining a reference to the ListBoxItem object through listBox.ItemContainerGenerator.ContainerFromIndex(0) after the ItemContainerGenerator status changes to ContainersGenerated and adding an event handler there. This event handler correctly fired. Normally this would be an ok solution on a small project but I plan on having more listboxes with the same sort of functionality and would like to have a simpler/better solution. Is there a way that I can get my base class previewkeydown method to work?
The only solution I could think of is to have the base class inherit from ListBoxItem instead of UIElement then get the ListBox to create my items instead of ListBoxItems. But I dont think that is really possible without creating my own ListBox implementation.
You seem to be somewhat confused. In WPF, we create data items and declare DataTemplates to define what those items should look like in the UI. Our data items do not extend UI classes. If you have to handle the PreviewKeyDown event, then attach a handler to the UI element in the DataTemplate instead:
<DataTemplate>
<Grid PreviewKeyDown="HomeViewMenuItem_PreviewKeyDown">
...
</Grid>
</DataTemplate>
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.
i have two separate projects inside a solution, one is a wpf the other is windows form and i have referenced the winform to the wpf project.. Inside the wpf window is an image control, when clicked, a windows form with a button would appear.
How i can be able to change the image source of the image control inside the wpf form when the button inside the winform is clicked...
i have seen a similar question to this but i cant understand the answers...
You could pass a delegate/Action into the Winform to perform the action
Here is a very quick example
WPF
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click_1(object sender, RoutedEventArgs e)
{
// pass in the method you want to call when the winform button is clicked
var winform = new Form1(() => ChangeImage()).ShowDialog();
}
private void ChangeImage()
{
// your change image logic
}
}
Winforms
public partial class Form1 : Form
{
private Action _action;
public Form1()
{
InitializeComponent();
}
public Form1(Action action)
{
_action = action;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (_action != null)
{
// call the method in the WPF form
_action.Invoke();
}
}
}
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()"