Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Access control's properties from another class in C# WPF

I'm in a mess with visibility between classes. Please, help me with this newbie question.

I have two controls (DatePickers from default WPF toolbox) which are in different windows, so in different classes. I can easily access these controls properties like datePicker1.Text from within its native class, i.e. in its native window, but when I try to reach datePicker1.Text from another window I get nothing.

I try to assign value of one datePicker to another, using reference to the window in my code:

string testStr;
...
AnotherWindow aw = new AnotherWindow();
testStr = aw.datePicker2.Text;
datePicker1.Text = testStr;

and it doesn't work

also I tried to do it through public property of a class, like:

public partial class AnotherWindow : Window
{
....

public string dateNearest
    {

        get { return datePicker2.Text; }
        set { datePicker2.Text = value; }
    }
....

and then use it in another window:

string testStr;
...      
AnotherWindow aw = new AnotherWindow();
testStr = aw.dateNearest;

but also no value assigned.

Please, help me to understand this basic issue. I know there are other ways of accessing values in WPF like databinding, but I would like to understand basics first.

like image 614
rem Avatar asked Oct 25 '22 23:10

rem


2 Answers

Unfortunately, the basics of WPF are data bindings. Doing it any other way is 'going against the grain', is bad practice, and is generally orders of magnitude more complex to code and to understand.

To your issue at hand, if you have data to share between views (and even if it's only one view), create a view model class which contains properties to represent the data, and bind to the properties from your view(s).

In your code, only manage your view model class, and don't touch the actual view with its visual controls and visual composition.

like image 105
Aviad P. Avatar answered Nov 11 '22 07:11

Aviad P.


I'm using VS 2010 beta 2 right now which crashes regularly doing the simplest WPF coding, like trying to duplicate your question's code :) : but consider :

Is it possible that using this syntax will "do the right thing" :

    public string dateNearest 
    { 
        get { return this.datePicker2.Text; } 
        set { this.datePicker2.Text = value; } 
    }

Edit 1 : Okay, I got a WPF replication of your code that didn't crash : using the above syntax I can both get and set the property in the "other window."

Edit 2 : The code also works using your original code :) Which, seemed to me to be "proper" the first time I read it. Are you setting that property before you read it ? : to my knowledge a DateTimePicker's Text property will be an empty string by default when first created.

Edit 3 : in response to Rem's request :

  1. the main window has a button, 'button1 : which tests setting and getting the Public Property DTContent defined in the instance of the second Window named : 'WindowAdded : here's the 'Click event handler for that button in the main window's code :

    private void button1_Click(object sender, RoutedEventArgs e)
    {
      WindowAdded wa = new WindowAdded();    
      wa.DTContent = DateTime.Now.ToString();
      Console.WriteLine("dt = " + wa.DTContent);
    }
    

Edit 4 : a better "real world" example : most cases you are going to want to create that instance of another window, and hold on to it, for re-use: imho : not have it exist only within the scope of a button's Click event. So consider, please :

Somewhere in the scope of the main window's code define a "place-holder" for the window(s) you will add : private WindowAdded wa;

In the event you select as most appropriate for creating the instance of that window : create the instance, and assign to your "place-holder" variable : then re-use it as needed. In WinForms I most often create required secondary windows that I will need to re-use references to the instances of to access something on them in the main form's load or shown events.

Discussion : of course, if your intent is to create "temporary" windows, and you don't need to re-use that reference to the new window's instance again, then creating it in the scope of some function is fine.

And, if the only thing you ever need to access on your second Window is the DateTimePicker, then you use the same technique suggested above, but create and hold to a reference to the instance of the DateTimePicker only.

like image 45
BillW Avatar answered Nov 11 '22 08:11

BillW