Dan
Dan

Reputation: 1001

Generic UI Update method

I'm currently working with async and await in C# and I want to create a method that update the UI without facing the problem of cross-thread updating. This is what I have at the moment

Model class:

public class UIModel
{
    public string ControlId { get; set; }
    public Type TypeOfControl { get; set; }

    public string PropertyName { get; set; }

    public object Data { get; set; }
    public Type TypeOfData { get; set; }
}

UI Updater method:

private void UIUpdater(UIModel model)
{
    var control = this.Controls.Find(model.ControlId, true).FirstOrDefault() as model.TypeOfControl.GetType(); // <- not valid
    // set control's model.PropertyName using model.Data
}

But I can't seem to get the method working, how do I cast the generic Control to say, a Textbox, or DataGridView, based on the control type defined in the UIModel.

And also how do I set the property for that control based on the property name defined in the UIModel?

Examples of UIModel:

new UIModel()
{
    ControlId = "textBox1",
    TypeOfControl = typeof(TextBox),
    PropertyName = "Text",
    Data = "The quick brown fox jumps over the lazy dog.",
    TypeOfData = typeof(string)
};

new UIModel()
{
    ControlId = "button1",
    TypeOfControl = typeof(Button),
    PropertyName = "Enabled",
    Data = false,
    TypeOfData = typeof(bool)
};

Upvotes: 0

Views: 148

Answers (1)

NeddySpaghetti
NeddySpaghetti

Reputation: 13495

var control = this.Controls.Find(model.ControlId, true).FirstOrDefault() as model.TypeOfControl.GetType()

The code above gives you an error because the as operator expects a type after the as keyword not and expression.

From the C# spec:

In an operation of the form E as T, E must be an expression and T must be a reference type, a type ?parameter known to be a reference type, or a nullable type.

You can filter the Controls collection using FirstOrDefault. I tried the code below and it works with the data you provided, correctly setting the Text property of a TextBox.

 var result = this.Controls.Find(model.ControlId, true).FirstOrDefault(x => x.GetType() == model.TypeOfControl);

 PropertyInfo prop = result.GetType().GetProperty(model.PropertyName, BindingFlags.Public | BindingFlags.Instance);
 if (null != prop && prop.CanWrite)
 {
    prop.SetValue(result, model.Data, null);
 }   

Upvotes: 1

Related Questions