Ситуация :
- Приложение UWP, использующее MVVM и Xaml для пользовательского интерфейса
- Модели представления получены из класса
ModelBase
, реализующего интерфейс INotifyPropertyChanged
Проблема :
- при выполнении указанного c теста пользовательского интерфейса с использованием затронутого класса, в некоторых случаях приложение выдает
InvalidCastException
во время звонка PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName))
. Свойство propertyName установлено правильно с помощью [CallerMemberName], которое было проверено с помощью записи в журнале отладки. Метод SetProperty
вызывается в DependencyProperty с полем поддержки. DebugConverter, используемый в элементе Xaml, который связан с событием PropertyChanged, показывает допустимое преобразование, но установка связанного элемента завершается неудачно. Похоже, что двойное удвоение невозможно, что не имеет смысла.
Вопрос
- У кого-нибудь есть идея, в чем причина это исключение может быть?
Код
Control.xaml
Maximum="{Binding TimeControlCanvasWidth, Converter={StaticResource DebugConverter}}" />
ModelBase.cs
public class ModelBase : INotifyPropertyChanged
{
/// <summary>
/// The event raised, when the property changed
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
{
try
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
catch (System.InvalidCastException)
{
LogManager.Current.GetLogger(GetType()).LogCritical(() => $"#####{nameof(OnPropertyChanged)}" +
$" - InvalidCastException | propertyName={propertyName}");
}
}
protected virtual bool SetProperty<T>(ref T field, T value, [CallerMemberName]string propertyName = null)
{
if (field?.Equals(value) == true)
{
return false;
}
field = value;
// ReSharper disable once ExplicitCallerInfoArgument
OnPropertyChanged(propertyName);
return true;
}
}
}
ViewModel.cs
public class TimeControlViewModel : ModelBase
{
private double _timeControlCanvasWidth;
public double TimeControlCanvasWidth
{
get => _timeControlCanvasWidth;
set
{
if (SetProperty(ref _timeControlCanvasWidth, value))
{
// do sth.
}
}
}
}