tags:

views:

231

answers:

3

I have form with lot's of TextBoxes and also there is a lot of threads in my program that need to read content's of those TextBoxes (settings). Since I can't access controls from other threads, I decided to make special class that will hold all the settings, and if user changes some, control will invoke OnTextChanged event and change corresponding value in class. But if I use that approach there will be a lot of similar handlers tike this

private void txtCrap1_TextChanged(object sender, EventArgs e)
{
    Settings.Crap1 = txtCrap1.Text;
}

What I want is to do something like this

private void SetUpControlBindings()
{
    AddBinding(txtCrap1, Settings.Crap1);
    AddBinding(txtCrap2, Settings.Crap2);
}
private void AddBinding(object control, object value)
{
    //Add entry to some kind of dictionary
}
private void UpdateValue(object sender, EventArgs e)
{
    if (sender is TextBox)
    {
    //Search it in dictionary and change appropriate value
    }
}

But I can't find any pointers to variables in C# Any ideas how to do this?

P.S. I can't use reflection since my code will be obfuscated after compilation

upd: Actually my program is a bit more complicated. I have not only textboxes, but CheckBoxes, NumericUpDowns etc. also I want my Settings class to hold some additional objects like Lists.

A: 

Make your Settings object backed by a Dictionary<string, string> that maps the names of the textboxes to their values.

For example:

readonly Dictionary<string, string> values = new Dictionary<string, string>();
public void AddBinding(TextBox box) {
    box.Change += TextBox_Change;
    values.Add(box.Name, box.Value);
}

void TextBox_Change(object sender, EventArgs e) {
    var box = (TextBox)sender;
    values[box.Name] = box.Value;
}

//Properties:
public string Prop1 { get { return values["textBox1"]; } } 
//Where textBox1 is the name of the textbox

Note

To use this on multiple threads, you'll need to use a ReaderWriterLockSlim.

SLaks
Actually my program is a bit more complicated. I have not only textboxes, but CheckBoxes, NumericUpDowns etc. also I want my Settings class to hold some additional objects like Lists.
Poma
You can still do this using multiple dictionaries change handlers with separate `AddBinding` overloads.
SLaks
A: 

Create a DataTable with a column for each TextBox, add a single row to it, and use normal Windows Forms data-binding. Then just treat the DataRow like a dictionary.

Coder 42
Actually my program is a bit more complicated. I have not only textboxes, but CheckBoxes, NumericUpDowns etc. also I want my Settings class to hold some additional objects like Lists.
Poma
I don't have a dev environment to hand right now, but your question is basically "how do I rewrite Windows Forms data-binding from scratch", and I'm telling you you don't need to. The BindingSource class will let you bind to an object perfectly well. Trust me, I've written really complicated programs with it, with CheckBoxes, RadioButtons, CheckedListBoxes, DateTimePickers and a dynamic LINQ-to-SQL syntax-highlighting editor, all using standard, out-of-the-box data-binding.
Coder 42
A: 

The way I normally would solve something like this is by using data bindings.

txtCrap1.DataBindings.Add("Text", Settings, "Crap1");
chkCrap2.DataBindings.Add("Checked", Settings, "Crap2");

The problem is of course the obfuscation. But when obfuscating you can exclude things, like entire classes, methods or properties. If possible you could exclude the properties of the Settings class from the obfuscation and then be able to use normal data bindings. How you would exclude a property depends on the obfuscation framework you use.

Robert Höglund