This has been my issue for long time,i have a method inside the main page to open application,
i need to invoke it when the user control is clicked. so when creating a usercontrol i need to pass this method and call it inside the usercontrol click event.
Right now am doing like this,
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
MainPage m = new MainPage();
m.openApplication("STOCK");
}
But its throwing a null reference exception.Help me on this.
Rather than creating an instance of your mainpage, you can pass the mainpage as an argument to the usercontrol and do it like below,
Usercontrol(Mainpage m);
private void Grid_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
m.openApplication("STOCK");
}
Creating an instance will make null references if values are not assigned.
Related
I'm creating a new window in On_Click method. First I tried this;
public partial class MainWindow : Window
{
CustomerOperations customerOperationsWindow;
public MainWindow()
{
customerOperationsWindow = new CustomerOperations();
InitializeComponent();
}
private void btnCustomer_Click(object sender, RoutedEventArgs e)
{
customerOperationsWindow.Owner = this;
customerOperationsWindow.Show();
}
}
It's not working so I started creating the window instance every time the user clicks on the Customers button. And I used the following codes.
private void btnCustomer_Click(object sender, RoutedEventArgs e)
{
CustomerOperations customerOperationsWindow = new CustomerOperations();
customerOperationsWindow.Owner = this;
customerOperationsWindow.Show();
}
In the new window, If user clicks to Main button, I want to navigate to main window.
private void btnMain_Click(object sender, RoutedEventArgs e)
{
this.Close();
this.Owner.Show();
}
First question: Does this.Close() releases the window instance?
Second question: Is this usage correct?
What do you think is the best practice?
Thank you all.
Window.Close() will dispose all resources allocated by the instance. That's why you cannot show it again once it was closed.
If you want to reuse the same Window instance, you should cancel the closing procedure to prevent disposal of internal resources and collapse the Window instead (by setting Window.Visibility to Visibility.Collapsed - Visibility.Collapsed is also the default value of an instantiated Window before Window.Show() is called).
Alternatively hide the Window by calling Window.Hide() (which will set the Visibility to Visibility.Hidden) instead of Window.Close().
Calling Window.Show will also set the window's visibility to Visibility.Visible.
As a matter of fact, showing a Window by setting Window.Visibility is the asynchronous version of Window.Show().
Generally, you switch between Window instances by using the Window.Activate method. Calling Window.Show on a Window that is currently showing/visible, does nothing.
public partial class MainWindow : Window
{
CustomerOperations CustomerOperationsWindow { get; }
public MainWindow()
{
InitializeComponent();
this.CustomerOperationsWindow = new CustomerOperations();
// Consider to move this logic to CustomerOperations class,
// where you can override the OnClosing method instead of subscribing to the event
this.CustomerOperationsWindow.Closing += CollapseWindow_OnClosing;
}
// Cancel close to prevent disposal and collapse Window instead
private void CollapseWindow_OnClosing(object sender, CancelEventArgs e)
{
e.Cancel = true;
this.CustomerOperationsWindow.Visibility = Visibility.Collapsed;
this.CustomerOperationsWindow.Owner.Activate();
}
private void btnCustomer_Click(object sender, RoutedEventArgs e)
{
this.CustomerOperationsWindow.Owner = this;
// Calling Show will set the Visibility to Visibility.Visible
this.CustomerOperationsWindow.Show();
}
}
Creating a Window instance allocates unmanaged resources. If this happens very frequently, you will keep the garbage collector busy. From a performance point of view you may want to avoid it and prefer to reuse the same instance.
In a common scenario this is not necessary. But since Window exposes a Hide() method, you may consider to use it instead of Close().
If you want to switch to the parent window, you can use the code this.Owner.Activate(); and if you want to close the current window, first this.Owner.Activate(); and then this.Close();.
When you enter this.Close(), the compiler does not execute the following lines after reaching it. And when a sample window still exists there is no need to recreate it
private void btnMain_Click(object sender, RoutedEventArgs e)
{
this.Owner.Activate();
this.Close();
}
I am using MahApps.metro WPF library with MVVM. I have a ViewModel from which I need to display a Dialog. The MetroWindow has ShowMessageAsync. But what is the proper way to access it from the ViewModel? As I understand I need a View instance but passing that into the ViewModel doesn't seem like a good approach.
Use following approach:
Take an Action<T> ShowMessageAsync in your ViewModel which you are binding with window.
Now create a behaviour for Window and use following code in behaviour
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.Loaded += AssociatedObject_Loaded;
}
void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
if (this.AssociatedObject.DataContext is WindowViewModel)
{
WindowViewModel vm = this.AssociatedObject.DataContext as WindowViewModel;
vm.ShowMessageAsync = OnShowMessageAsync;
}
}
private void OnShowMessageAsync(T param)
{
//Write your logic to call ShowMessageAsync method.
}
Now in this way, from the ViewModel of your MainWindow you will have ability to open another child window.
private void btnConfirmInMyForm_Click(object sender, RoutedEventArgs e)
{
//for example without creating like this
MainWindow mainWin = new MainWindow();
mainWin.txtBirthDate.Text = "anything";
this.close();
}
when i try the above, content of the txtBirthDate of new instance of MainWindow (mianWin) changes to "anything", but not in current MainWindow!
in other words as i click btnConfirmInMyForm in MyForm it opens a new MainWindow with the txtBirthDate textBox contains "anything", which i don't want!
i only want to set the txtBirthDate from MyForm, not to create a new MainWindow that contains this!
with best regards
Is btnConfirmInMyForm_Click within your window? Then just try
this.txtBirthDate.Text = "anything";
If your MainWindow is the Application's MainWindow, then you could try something like:
private void btnConfirmInMyForm_Click(object sender, RoutedEventArgs e) {
var mainWindow = Application.Current.MainWindow as MainWindow;
if (mainWindow != null)
mainWindow.txtBirthDate.Text = "anything";
}
If it isn't you'd could pass your MainWindow object to the other Window to then use that object and assign the Text. You could also use something like a messaging pattern from MVVM to send messages across Views. There are quite a few options. What you pick is pretty much upto you.
Basically a RoutedEvent travels through the Logical tree, either from top to bottom (Bubble event route) or bottom to top (Tunnel event route).
What this means is that if you have a Button inside of a StackPanel, that itself is inside of a Grid;
if you define a Click event in the controls they will all trigger it unless one of them handles it.
In my application I have:
Button -> StackPanel -> Grid
If it’s true, that StackPanel and Grid will not trigger it.
Grid -> StackPanel -> Button
if the Grid handles it, the StackPanel and Button will not trigger it.
in my application i wrote:
private void Button_Click(object sender, RoutedEventArgs e) {
Response.Redirect("http://www.legalbill.com");
}
it gave this-
Error - The name 'Response' does not exist in the current context …
what it means n how will i move to desired site?
Are you sure you are trying to do this in wpf ? If you are trying in silverlight,It doesn't support Response.Redirect.You can use like this
using System;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
namespace Tips
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// execute one of them.
HtmlPage.Window.Navigate(new Uri(“http://www.silverlight.net“));
HtmlPage.Window.Navigate(new Uri(“http://www.silverlight.net“), “_blank”);
HtmlPage.Window.Navigate(new Uri(“http://www.silverlight.net“), “_blank”, “toolbar=0″);
}
}
}
I have a button inside my UserControl. I have three instances of this UserControl on the same page.
How can I expose the click event of the button inside such that I can assign different events for each instance of my UserControl.
I think this is similar to concept behind exposing DependencyProperty but I don't understand how to do it for events.
Thanks.
I normally add an event of the same name (and same parameters) to the user control and subscribe to the child control's original event, so I can pass the event on:
public partial class ClickEventControl : UserControl
{
public event EventHandler<RoutedEventArgs> Click;
public ClickEventControl()
{
InitializeComponent();
}
private void aButton_Click(object sender, RoutedEventArgs e)
{
if (Click != null)
{
Click(sender, e);
}
}
}
I would also be interested if there is a more general way of doing it.