What is the best way to exchange data between a WPF window and its user controls?

Sometimes WPF can sometimes be infuriating.

I have a fairly simple application consisting of one main window containing a tab control and several tabs. I did not like the idea of ​​having code for all tabs in a single file, so I used the answer from this question to split each tab into a separate user control.

In my main window, I have an instance of an object that contains application parameters and some other application data. Some of my tabs require access to this data for data binding purposes. I could not find a good way to achieve this.

First, I tried to access the parent window in the Loaded controls and get a link to the property in the main window that opened the settings object, as shown in the code below. This type of work, with the exception of the Loaded event, is triggered every time a tab receives focus. In addition, this event occurs at the end of the control life cycle, so I cannot bind to any properties of this object in the XAML user control.

private void MyUserControl_Loaded(object sender, RoutedEventArgs e) { this.ApplicationSettings = ((MainWindow)Window.GetWindow(this)).ApplicationSettings; } 

Then I experimented with passing data to the custom control constructor, but this does not exist in XAML.

Given that these are the parameters of the entire application, I could make the SingleSeries ApplicationSettings class and refer to it everywhere, but I would prefer not to do this to test the modules.

So how can this be done? Is my approach fundamentally wrong? In my opinion, all these user interface elements are part of the same window and therefore must have access to data from the main window, but the object model does not seem to allow this.

+6
source share
3 answers

You can put the settings object in a static property in a wrapper class ( SettingsHolder in this example and use its application through

in XAML:

 {Binding SettingName, Source={x:Static local:SettingsHolder.Settings}} 

with local being the namespace that your SettingsHolder class is in.

in code:

 var x = SettingsHolder.Settings.SettingName; SettingsHolder.Settings.SettingName = x; 
+2
source

In the declaration of your user control, you can simply set the data context to an instance of an object that contains everything you need to bind!

<someNamespace:EricsUserControl DataContext="{Binding InstanceOfBindingObject}"/>

You can then access the instance properties of these objects in the user control, as usual.

+1
source

I use Frame in Tab and put Page in Frame . (but I think the same thing can be applied with User Control). The designer starts only when the page is created, and you can control when the page is created, and you can pass information to the designer. The page has more lifecycle events. I also use the Loaded event to create the user interface (it just fires once). If you anchor the page in XAML, it fires when the application starts, and you cannot transfer information. This creates a page and displays it in a dialog box, but this page can be anchored to the frame.

  NavigationWindow winSearchXML; using (new WaitCursor()) { winSearchXML = new NavigationWindow(); winSearchXML.Content = new PageSearchResultsXML(GabeLib.GetSearchXML(GabeLib.enumXMLtype.Flat)); } winSearchXML.ShowDialog(); 

I need to be honest that several times I get a life cycle on a page that I just don't understand. So take it with salt. But the fact is that you have a contructor and loaded events that can give you what you need.

0
source

Source: https://habr.com/ru/post/905408/


All Articles