Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I pass data between WPF Windows involving `MainWindow` (C#)?

Tags:

c#

window

wpf

I am currently starting a C# project in which I am modelling a simple ATM machine, and will therefore need several screens. I have run into the problem of passing data between screens before when I was coding a StockTicker board game adaption, but I don't think my method of solving it was very good.

A lot of my problems stem from the fact that I use MainWindow as the primary window of the application. I am able to easily pass data from the secondary window back to the primary window, as I am able to access the properties of the Window1 class after it has been closed. However, to tranfer from MainWindow to Window2, I have to add a parameter to the constructor of Window2 that will enable me to pass in the necessary values.

While this does work for a small application, it is my opinion that this would get very long/messy for the more things that need to be passed to Window2. In addition, I do not know at all how to access any of the methods that I declare on MainWindow from Window2. Since MainWindow is the primary screen, most of my coding is in its class.

  • How can I access a method that I have put in MainWindow from Window2 ??

(For clarification) I have spent some time looking around, and cannot find a clear example that specifically involves MainWindow, and needing to access variables/methods found in it.


Here is my C# code (I have tried to have clear variable names). The gist of the program is that you can have some data stored on Form 1, which then is passed to Form 2 when the button is clicked. From here, it can be modified however the user wishes, and then it can be accessed again from Form 1 when Form 2 is closed.

In this example, I am merely showing that I have found a way to transfer data from form to form, but I am sure that there is a better way. Specifically, I am sure that there is a nicer way than having to possibly code different constructors with varying paramaters for the Window2 class.


First WPF Window Code:
namespace Banking_System
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnSwitchForm_Click(object sender, RoutedEventArgs e)
        {
            string strForm1Text = txtForm1TextBox.Text;

            Window2 newWindow = new Window2(strForm1Text);
            newWindow.ShowDialog();

            txtForm2TextBox.Text = newWindow.strForm2Text;
        }
    }
}

Second WPF Window Code:

namespace Banking_System
{
    public partial class Window2 : Window
    {
        public string strForm2Text { get; set; }

        public Window2(string form1)
        {
            InitializeComponent();

            txtForm1.Text = form1;
        }

        private void btnSwitchBack_Click(object sender, RoutedEventArgs e)
        {
            strForm2Text = txtForm2TextBox.Text;
            this.Close();
        }
    }
}

Would I be better off to create another WPF window, and have it load as soon as the MainWindow loaded, and then hide MainWindow and "pretend" that the other window was the primary screen? Because then I could simply access the properties in the same manner that I do above (when transferring from Window2 to MainWindow).

ie. When needing to access a variable/method from another window, simply declare a new temporary window and access the properties/methods of it:

FakeMainWindow wndPrimary = new FakeMainWindow();
wndPrimary.strProperty= "test";
wndPrimary.methodCall();

The primary attraction of this way for me is that I can access methods on another window (as illustrated above), which I cannot do while using MainWindow as my primary form.

Summary

  • How can I access a method that I have put in MainWindow from Window2?
  • Is it better to create another WPF window, and pretend that it is my "primary screen" so that I can easily access its properties?
  • If not, is there a better way of working with MainWindow?

If I'm missing anything, let me know. Thanks!

like image 840
Kendall Avatar asked May 05 '15 21:05

Kendall


People also ask

How can I access a control in WPF from another class or window?

How can I access a control in WPF from another class or window? If you want to access a control on a wpf form from another assembly you have to use the modifier attribute x:FieldModifier="public" or use the method proposed by Jean. Save this answer.

How do I navigate between pages in WPF?

You can navigate from one Page to another declaratively, by using a Hyperlink, or programmatically, by using the NavigationService. WPF uses the journal to remember pages that have been navigated from and to navigate back to them.

What is the difference between a page and a window in WPF when you are adding a new file in the Solution Explorer?

Window is the root control that must be used to hold/host other controls (e.g. Button) as container. Page is a control which can be hosted in other container controls like NavigationWindow or Frame. Page control has its own goal to serve like other controls (e.g. Button). Page is to create browser like applications.


3 Answers

You can actually access your application's main window without passing any references between windows. Application.Current.MainWindow returns the instance of the main window that is declared in app.xaml. It returns a Window (which your main window derives from) so you will need to cast it in order to access its members.

For example, you could use this code in your second window:

((MainWindow)Application.Current.MainWindow).txtForm1TextBox.Text = "Some text";

Having said that, I kindly suggest that you do some research into WPF design patterns (specifically MVVM).

like image 147
learningcs Avatar answered Nov 17 '22 07:11

learningcs


Pass the whole window
this will be MainWindow

Window2 newWindow = new Window2(this);
like image 44
paparazzo Avatar answered Nov 17 '22 07:11

paparazzo


You can set the First window as the Second window's DataContext :

 namespace Banking_System
 {       
     public partial class MainWindow : Window
     {
        public MainWindow()
        {
            InitializeComponent();           
        }

        private void btnSwitchForm_Click(object sender, RoutedEventArgs e)
        {               
            Window2 newWindow = new Window2(strForm1Text);
            newWindow.DataContext = this;
            newWindow.ShowDialog();      
        }            
  }

 public partial class MainWindow2 : Window
 {
      public MainWindow2()
      {
         var window1 = this.DataContext;
      }
 }  

}

Additionally i would recommend that your Window would have it's own ViewModel set as it's DataContext which you can send to the other window. In this way you can also bind properties directly to both windows and not worry about updating them manually .

like image 1
eran otzap Avatar answered Nov 17 '22 08:11

eran otzap