Where do you put global variables in a WPF application?
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, 开发者_Go百科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.";
}
}
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.
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.
App.Config (double click the Properties node in the project) for primitives that are user specific (read/write) and application specific (read only).
For complex types such as providers (database, logging, etc), there isn't "one" place. But the best pattern today is to use some form of dependency injection such as Unity or NInject.
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.
While I share the general lack of enthusiasm for globals, it's worth at least acknowledging the central WPF mechanism for global information: the application's resource dictionary. There are a lot of things you shouldn't use this for (like, you can create a singleton-like object just by putting an XML data source in your application's resource dictionary, but really, don't), but there are a lot of things that you should - global styles, global templates, etc.
精彩评论