Closed danielklecha closed 4 years ago
Hi @danielklecha , I had a similar problem in the past. For me this was solved with this change: #3540 . This will be available in the upcomming v2.0.0. You can test this in the current prerelease if you want to. But please keep in mind that there are many breaking changes. So maybe don't try it in your productive environment.
Happy coding Tim
@timunie Unfortunatelly that doesn't fix my issue.
So I have this situation
For some reason after commit edit in point 4 Validation.HasError is not synchronized with HasErrors property...
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnNotifyDataErrors=True, NotifyOnSourceUpdated=True,NotifyOnTargetUpdated=True, NotifyOnValidationError=True}"/>
<DataGridCheckBoxColumn Binding="{Binding HasErrors, Mode=OneWay}" Header="HasErrors"/>
<DataGridTextColumn Binding="{Binding (Validation.HasError), Mode=OneWay, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Header="Error"/>
</DataGrid.Columns>
Also I simplify my record class and run each event manually but it doesn't help...
[DoNotNotify]
public class MyRecord : Caliburn.Micro.PropertyChangedBase, INotifyDataErrorInfo
{
private readonly AbstractValidator<MyRecord> _validator;
private string _name = string.Empty;
private Dictionary<string, List<string>> _errors = new Dictionary<string, List<string>>();
public MyRecord(FluentValidation.AbstractValidator<MyRecord> validator)
{
_validator = validator;
Validate();
this.PropertyChanged += (s, a) => Console.WriteLine($"MyRecord - PropertyChanged - {a.PropertyName}");
this.ErrorsChanged += (s, a) => Console.WriteLine($"MyRecord - ErrorsChanged - {a.PropertyName}");
}
public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged;
public bool HasErrors => _errors.Any();
public IEnumerable GetErrors(string propertyName)
{
Console.WriteLine($"MyRecord - GetErrors - {propertyName}");
if (string.IsNullOrEmpty(propertyName))
return Enumerable.Empty<string>();
if (!_errors.TryGetValue(propertyName, out List<string> value))
return Enumerable.Empty<string>();
Console.WriteLine(value.Count);
return value;
}
private void Validate()
{
Console.WriteLine("MyRecord - Validate");
if (_validator == null)
return;
var previousKeys = _errors.Select(x => x.Key).ToList();
_errors = _validator.Validate(this)
.Errors
.GroupBy(x => x.PropertyName)
.ToDictionary(x => x.Key, x => x.Select(y => y.ErrorMessage).ToList());
}
public string Name {
get => _name;
set
{
Console.WriteLine($"MyRecord - Name - begin");
_name = value;
NotifyOfPropertyChange("Name");
Validate();
ErrorsChanged(this, new DataErrorsChangedEventArgs("Name"));
NotifyOfPropertyChange("HasErrors");
Console.WriteLine($"MyRecord - Name - end");
}
}
}
Hi @danielklecha,
I am not familar with INotifyDataErrorInfo
. In my App I still use IDataErrorIInfo
. Can you upload a sample project here? I will hava a look if I can help then.
Happy coding Tim
Hi @timunie, I uploaded sample project to github. I added two grids. One with records with IDataErrorInfo and second with INotifyDataErrorInfo. In both cases I have the same situation:
Maybe I do something wrong. Wrong order or something... I don't have a problem to use IDataErrorInfo interface but this also doesn't work...
I simplified dependecies - removed caliburn micro and fody and added simple base class.
Thank you for checking this β much appreciated. Best Daniel
Hi Daniel, many thanks for your sample. i now understand your annoying problem. I think this bug comes not from MahApps itself, so I don't know if we can solve this issue here. Searching the web, I found this:
In the case you find a solution, please share it here π
Good luck Tim
Hi Daniel,
one addition: If I change UpdateSourceTrigger
to LostFocus
the red exclamationmark works as expected for me.
Happy coding Tim
Hi Tim, I changed UpdateSourceTrigger to LostFocus and DataGrid with IDataErrorInfo stated working. INotifyDataErrorInfo interface still generates incorrect data.
I will try to use IDataErrorInfo in my project. In my real case I use ICustomTypeDescriptor and this is adding new layer of problems... BUT I have working example thanks to you!
Also thanks for links. My plan B is to update MahApps style for row error and change Validation.HasErrors to DataContext.HasErrors or something like that. The same for error message in tooltip. Plan C is to create custom rule which will red informations from interface properties.
Thank you very much for your help. Best Daniel
You are welcome
I tested DataGrid with IDataErrorInfo. Everything is working when UpdateSourceTrigger is set to LostFocus. Binding mode can't be set to TwoWay but we can use Default and control finally use TwoWay as expected. Also I tested it with my implementation of ICustomTypeDescriptor and wverything is correct.
I was not able to get working example for INotifyDataErrorInfo interface. I suspect that something is wrong with this interface ant it can't work with DataGrid.
For now I think that we can close this thread. @timunie once again thanks for help!
Hi @danielklecha
Now I got the same issue as you. I moved to INotifyDataErrorInfo
due to performance issues. I have at least two ideas to solve this issue.
If you are still interested in a solution please reopen this issue.
Happy coding Tim
Update @danielklecha
What I have tried both ideas, without luck. For now I will just use only the Cell-Validation as it works as Expected.
Happy coding Tim
Ok one more Update:
at least I found a workaround by setting a custom RowHeaderTemplate
.
@danielklecha : if you are interested in this please let me know. My cuurent implementation is not ready to be shown π
@punker76 : are you interested in adding this to the documentation?
Happy coding Tim
Hi @timunie
I'm using IDataErrorInfo and so far I'm happy with that.
Yes, I'm still interested with INotifyDataErrorInfo. I suppose that you modified MahApps.Styles.DataGridRowHeader style and replace Validation.HasError with DataContext.HasErrors - or something similar. But even with that error icon don't update message in tooltip. So there should be some custom property similar to IDataErrorInfo.Error with first error and associate it to tooltip in MahApps.Templates.DataGridRow.ValidationError. I didn't had a time to update my demo app.
Anyway, it's still a workaround because of broken usage of INotifyDataErrorInfo interface.
Best Daniel
Hi @timunie I updated my demo with my custom style and everything is working with INotifyDataErrorInfo (second data grid). I used INotifyDataErrorInfo.HasErrors and custom property Error. Probably style should be moved to separate file. Download changes and check it.
I had a problem to use "MahApps.Brushes.Controls.Validation" and "MahApps.Brushes.Text.Validation" styles so I copied it manually. I'm not a fan of this solutions but I don't see a better way for INotifyDataErrorInfo.
Btw I didn't tested it with .NET Core - maybe they fixed this interface.
Hi @danielklecha ,
I had a problem to use "MahApps.Brushes.Controls.Validation" and "MahApps.Brushes.Text.Validation" styles so I copied it manually. I'm not a fan of this solutions but I don't see a better way for INotifyDataErrorInfo.
Note: You use MahApps v1.6.5. The StyleKeys
are valid for the prerelease v2.0.0alpha.
Here is my implementation: https://github.com/timunie/WpfDataGridValidation/tree/CustomValidationExample
Please wait for the feedback of @punker76 bevore you close this issue.
Happy coding Tim
Thanks for example @timunie. Your solution with tooltip is better than mine (with additional property).
Description
Am I implemented it incorrectly? Or it's an issue in header style?
Environment
Nuget libraries
Code
MainWindow view
MainWindow bode behind
App.xaml