Where do you put global variables in a WPF application?
Solution 1
Globals? just say no. (sorry, someone had to say it) for config stuff, as suggested by others, use the App.Config,
The code you provided looks like a M-V-VM to me--you should check it out. WPF, by it's nature, promotes this. Learn it, love it, live it.
Solution 2
I consider the sort of global state that I think you're describing to be configuration information. Resultantly, I place it in the App.config file, generally through the project's properties' "Settings" tab.
This will expose your configuration information through <WhateverNamespace>.Properties.Settings
where it's easy to access in a typesafe manner.
If you're describing something else, such as mutable application state that isn't configuration information, I'd strongly suggest shifting your paradigm to a more client-application form where such global state is strongly frowned upon due to it's error-prone nature. IE, restructure your application model so that it doesn't depend on global data-- use parameters and objects instead.
Solution 3
Try this
/// <summary>
/// "Global variables" or kind of "Session State" class.
/// To save a variable: ApplicationState.SetValue("currentCustomerName", "Jim Smith");
/// To read a variable: MainText.Text = ApplicationState.GetValue<string>("currentCustomerName");
/// </summary>
public static class ApplicationData
{
/// <summary>
/// Get an application-scope resource Formatted News
/// </summary>
/// <returns></returns>
public static DataContainerModel GetNews()
{
var formattedNews = (DataContainerModel)Application.Current.Resources["FormattedNews"];
return formattedNews;
}
/// <summary>
/// Set an application-scope resource Formatted News
/// </summary>
/// <param name="dataContainerModel"></param>
public static void SetNews(DataContainerModel dataContainerModel)
{
Application.Current.Resources["FormattedNews"] = dataContainerModel;
}
private static ConcurrentDictionary<string, object> _values = new ConcurrentDictionary<string, object>();
public static void SetValue(string key, object value)
{
if (_values.ContainsKey(key))
{
var oldValue = new object();
_values.TryRemove(key, out oldValue);
}
_values.TryAdd(key, value);
}
public static T GetValue<T>(string key)
{
if (_values.ContainsKey(key))
{
return (T)_values[key];
}
else
{
return default(T);
}
}
}
So here you see two approaches. I would like to have both of them.
Oh! DataContainerModel
is going to be any custom class you need.
Angry Dan
web/software developer, .NET, C#, WPF, PHP, software trainer, English teacher, have philosophy degree, love languages, run marathons my tweets: http://www.twitter.com/edward_tanguay my runs: http://www.tanguay.info/run my code: http://www.tanguay.info/web my publications: PHP 5.3 training video (8 hours, video2brain) my projects: http://www.tanguay.info
Updated on June 05, 2022Comments
-
Angry Dan almost 2 years
In PHP web programming, I always made a singleton Output object in which I could put global information that had to be available from any line of code.
So in WPF applications, I create the following class to perform the same function, e.g. the variable
ReturnToPageIdCode
returns the page to which another page is supposed to return to after processing some task, and I can set and get that value anywhere I want.This works nicely.
However, I can't help to think that in the stateful WPF environment, I'm recreating the wheel with this singleton Output object.
Where do you put hold application-wide values in your WPF applications? Is there some standard place to do this?
public class Output { private Output output; private static Output instance; public string ReturnToPageIdCode { get; set; } public static Output GetInstance() { if (instance == null) { instance = new Output(); } return instance; } public string GetTestMessage() { return "This is a global test message from the output singleton."; } }