basti
basti

Reputation: 2689

How to change property of every control in application

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

Answers (3)

Dean Chalk
Dean Chalk

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

Dr Herbie
Dr Herbie

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

Scott Chamberlain
Scott Chamberlain

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

Related Questions