I am quite unsure if that is the proper solution but the only working way to achieve what I want that I found so far is to wrap SomeModel
with a sort of "wrapper" for it that has all it's properties typed as string
.
Something like this:
public class SomeModel(decimal someNum = 10.0m)
{
public decimal SomeValue = someNum;
}
public class SomeModelWrapper(SomeModel data) : ObservableObject, INotifyDataErrorInfo {
private SomeModel rawData = data;
private string someValue = data.SomeValue.ToString();
public string SomeValue { get => someValue; set
{
if (SetProperty(ref someValue, value))
{
// exctractValueFromString adds "nice" validation error
// if value cannot be converted.
var convertedValue = extractValueFromString(value);
if (convertedValue != null)
{
// Handle validation here
...
// Update underlying data
SetProperty(ref rawData.SomeValue, convertedValue, nameof(SomeValue));
}
}
}
// Implement INotifyDataErrorInfo
...
}
The extractValueFromString
method accepts string value that we need to convert and tries to parse it into needed type. And if it fails it returns null and adds a validation error for this property.
Now instead of binding DataGrid to actual data in SomeModel
I bind it to that "wrapper". This way whenever value in DataGrid changes it is always accepted regardless of it being convertible to target type (the one in SomeModel
) and I handle that conversion (and it's errors) myself.
It looks quite bad and adds a lot of extra code with potentially some other problems but it seems to work for me and all the extra problems hopefully are MY problems now and not framework's (which means I don't have to wait for framework devs to solve them for me)