WPF can be infuriating sometimes.
I have a fairly simple application that consists of a single main window that contains a tab control and several tabs. I did not like the idea of having the code for all tabs in the same file, so I used the answer from this question to break out each tab into a separate user control.
Inside my main window I have an instance of an object that contains application settings, and some other application-wide data. Several of my tabs require access to this data for data binding purposes. I have not been able to find a good way to accomplish this.
First I tried to access the parent window in the controls Loaded event and get a reference to the property in the main window that exposed the settings object, as shown in the code below. This kind of works, except the Loaded event is fired every time the tab gains focus. Also, this event occurs late in the control life cycle so I am not able to bind to any of the properties in this object in the user controls XAML.
private void MyUserControl_Loaded(object sender, RoutedEventArgs e)
{
this.ApplicationSettings = ((MainWindow)Window.GetWindow(this)).ApplicationSettings;
}
Then I experimented with passing the data into the user controls constructor, but there is no way to do that in XAML.
Given that these are application-wide settings I could make the ApplicationSettings class singleton and reference it everywhere, but I would prefer not to do that for unit testing purposes.
So how does one accomplish something like this? Is my approach just fundamentally flawed? In my mind all of these UI elements are part of the same window and therefore should be able to access data from the main window, but the object model does not appear to allow this.
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.
A window is managed by the OS and is placed on the desktop. A UserControl is managed by wpf and is placed in a Window or in another UserControl. Applcations could be created by have a single Window and displaying lots of UserControls in that Window.
You could put the settings object into a static property in a wrapper class (SettingsHolder
in this example and reference it application wide via
in XAML:
{Binding SettingName, Source={x:Static local:SettingsHolder.Settings}}
with local
being the namespace your SettingsHolder
class is in.
in Code:
var x = SettingsHolder.Settings.SettingName;
SettingsHolder.Settings.SettingName = x;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With