Reputation: 1001
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
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