Reputation: 614
Apologies as I am new to generics (which is what I believe is needed in this scenario).
I want to pass the BindingList variable to a method that performs an update on a defined property, and then returns a pass/fail (true/false) value. This appears to be harder than I thought it would be, so could use some help. Here is working and non-working code.
First, I have a class with a BindingList (working):
public class BookMetaData : INotifyPropertyChanged
{
private string _bookMetaDataTitle;
[DescriptionLocalized(typeof(ResourcesClassBooks), "BookMetaDataTitleComment")]
[DisplayNameLocalized(typeof(ResourcesClassBooks), "BookMetaDataTitleDisplayName")]
public string BookMetaDataTitle { get { return _bookMetaDataTitle; } set { SetField(ref _bookMetaDataTitle, value, "BookMetaDataTitle"); } }
#region handle property changes
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetField<T>(ref T field, T value, string propertyName)
{
//if the value did not change, do nothing.
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
//the value did change, so make the modification.
field = value;
return true;
}
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
Next, I create a variable that represents the binding list (working):
BindingList<BookMetaData> bookMetaData = new BindingList<BookMetaData>(); //metadata for the books
Prepare to send the class variable and specific property to update to a generic method. Please note, this technically works, but the remaining code does not:
private bool Test()
{
//the code below would probably be in a foreach loop and would not pass a single index.
ProcessBookTitle(bookMetaData, 0, typeof(BookMetaData).GetProperty(nameof(BookMetaData.BookMetaDataCoverage)));
return true;
}
I want this generic method (is it called a method?) to update the BindingList class variable's specified property. If something goes wrong in the general business logic, that return false. Otherwise, return true (not working):
private void ProcessBookTitle<T>(BindingList<T> bindingList, int classIndex, PropertyInfo prop)
{
try
{
//do some things...
//If I manually wrote the next line, it would look like this:
//bookMetaData[0].BookMetaDataTitle = "My Book Title";
bindingList[classIndex].prop = "My Book Title"; //error = 'T' does not contain the information for 'prop'...
//maybe do some other things...
return true; //cannot find a way to return bool.
}
catch
{
//something went wrong somewhere, so return false.
return false; //does not work because cannot return a bool.
}
}
Is there a way I can send the name of the class variable and the property to update to another method? Also, is it possible to do this within a method that returns bool (and or some other way of returning success or failure)?
Thanks in advance for any help you can provide.
EDIT: The requirement to return a bool is to ensure the passing method knew whether the overall process was successful. Updated code to show this.
Upvotes: 2
Views: 1979
Reputation: 765
You can use reflection for this as @Yacoub Massad mention. If you are wondering how then it's like this. What we are doing here is getting the type of generic type T and access its property information. Now since you mentioned reading from file, parsing information etc, I suggest you look into Delegate Actions With Return Values. But that it self is another story to tell.
static private bool ProcessBookTitle<T>(BindingList<T> bindingList, int classIndex, string propertyName)
where T : class
{
try
{
Type type = typeof(T);
PropertyInfo propertyInfo = type.GetProperty(propertyName);
object val = "Do some processing whatever here.";
propertyInfo.SetValue(bindingList[classIndex], Convert.ChangeType(val, propertyInfo.PropertyType), null);
return true;
}
catch (Exception ex)
{
// do something with the exception
return false;
}
}
Upvotes: 2