You can use the Redux pattern that is used in web pages made with React, with that you manage the status of your application globally, and it is thread-safe since the state is immutable.
Examples of implementations of the Redux pattern in C # have several:
You have Redux.Net: link
O Reducto:
link
Here is an example with Reducto (which is the one I used):
First define a structure where the data you want to have globally will be:
public struct AppState
{
public string ValorLabel; // este sería el texto que quieres poner en los labels en todos los formularios
}
Then you create an "action" for each data you have declared, you can only modify the status by means of actions, not directly:
// esta acción cambia el valor de la label a otro texto
public struct CambiaLabel {
public string NuevoValor { get; set;}
}
// esta acción borra el texto de la label
public struct BorraLabel {
// no le agregamos ninguna propiedad porque simplemente borra el texto
}
Then you create the reducers, the reducers are those that modify or alter the state:
var reducer = new SimpleReducer<AppState>()
.When<CambiaLabel>((state, action) => {
// la store nos pasa el estado actual (en state) y la acción que se va a realizar (en action)
state.ValorLabel = action.NuevoValor; // modificamos el estado con el valor que viene en la action
return state; // regresamos el nuevo estado
})
.When<BorraLabel>((state, action) => {
// de nuevo la store nos pasa el estado actual (en state) y la acción a realizar, pero en este caso la acción no trae ningún parámetro
state.ValorLabel = string.Empty; // modificamos el estado
return state; // regresamos el estado
});
And finally you create the store object, which is the one that contains the status of your application:
var store = new Store<AppState>(reducer); // le pasamos el reducer que creamos anteriormente
You can do a singleton without problem, just declare it read only:
public static class Store
{
readonly Store<AppState> store;
static Store()
{
var reducer = new SimpleReducer<AppState>()
.When<CambiaLabel>((state, action) => {
state.ValorLabel = action.NuevoValor;
return state;
});
store = new Store<AppState>(reducer);
}
public static Store<AppState> Instance => store;
}
And ready, to update the status you just have to write:
private void button1_Click(object sender, EventArgs e)
{
Store.Instance.Dispatch(new CambiaLabel { NuevoValor = "Hola mundo" });
}
You can do it from anywhere in the code.
And to know when the status changes (and so you update in all views):
// Subscribe se va a ejecutar cada vez que en alguna parte se modifica el estado por medio de una acción
Store.Instance.Subscribe(state = {
// en state nos llega el estado ya actualizado
// y puedes usarlo para lo que quieras
label.Text = state.ValorLabel;
});
For example, if you have several forms and want to have a label that says the same thing in all of them, because you use the code above in each one, and its content will be synchronized.
The idea is that you do not fall into bad habits falling into the temptation of using a mutable Singleton, which is not recommended, an immutable singleton is better.