Reputation: 2689
what I want to do is to give the user the ability to change some (here one) property of all text boxes in my application. When the user triggers my event, every textbox in every usercontrol, panel etc. is ought to be changed.
For Example all textboxes should change to Multiline=true;
(I know this doesn't make much sense, but my needs a really similar to this), but how to achieve this without looping over every control?
I know I could do something like
foreach(Control item in FindForm().Controls)
{
if(item is TextBox)
{
(item as TextBox).Multiline=true;
}
}
but I don't think that this is a perfect nor a good solution.
I know I could write the settings to a file and read them when the app is starting, but how to change the properties while running the application?
My main problem know is that the ControlProperties don't let me give them a reference to a boolean object, so I can't easily change it in a "settings-object", or do I miss here something?
Upvotes: 2
Views: 1316
Reputation: 20451
Maybe you could just use a data trigger and a globally accessible utility class:
Here's an example where at the click of a button all textblock's will have a red foreground
<Window x:Class="RoomUnit.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:RoomUnit" Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<c:Utility x:Key="utility" />
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding Source={StaticResource utility},
Path=IsRed}" Value="true">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="TEST" />
<Button Content="Make Red" Grid.Row="1" Click="MakeRed" />
</Grid>
heres the utility class
public class Utility : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private bool isRed;
public bool IsRed
{
get { return isRed; }
set
{
isRed = value;
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("IsRed"));
}
}
}
and heres my button eventhandler
private void MakeRed(object sender, RoutedEventArgs e)
{
var u = (Utility) this.FindResource("utility");
u.IsRed = true;
}
Upvotes: 0
Reputation: 3940
In these circumstances you have two basic options: push the changes to the control (as you sample code does) or have the controls themselves pull the data from the configuration.
Using a pull approach will allow you to update controls at runtime. You could use databinding on all of your textboxes to bind the 'Multiline' property of the textboxes to some central store of the setting. You could go further and derive custom textbox controls that automatically handle their own databinding setup on instantiation, so once you have replaced the textboxes with your own textbox type (this can actually be done with a search and replace in the code) you don't have to make any more code changes.
Upvotes: 0
Reputation: 127543
I don't know of any good tutorials to walk you through it but you can do a DataBinding to any property (including Multiline) not just the text one. This should do what you need to do.
this.txtField.DataBindings.Add(
new System.Windows.Forms.Binding("Multiline",
global::ProjectNamespace.Properties.Settings.Default,
"BoolianSettingInConfigFile",
true,
System.Windows.Forms.DataSourceUpdateMode.OnPropertyChanged));
I used the config file in this example but it can be stored anywhere.
Upvotes: 2