修复 UWP 枚举 DependencyProperty 中的 ArgumentException
Fixing ArgumentException in UWP enum DependencyProperty
我在 UWP 应用程序中有以下代码:
public sealed partial class CanvasMapControl : UserControl
{
public static readonly DependencyProperty ActiveInteractionModeProperty =
DependencyProperty.Register(nameof(ActiveInteractionMode),
typeof(InteractionMode),
typeof(CanvasMapControl),
new PropertyMetadata(InteractionMode.None, CanvasMapControl_InteractionModeChanged));
public InteractionMode ActiveInteractionMode {
get => (InteractionMode)GetValue(ActiveInteractionModeProperty);
set => SetValue(ActiveInteractionModeProperty, value);
}
private static void CanvasMapControl_InteractionModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
((CanvasMapControl)obj).InteractionModeInternal = (InteractionMode)args.NewValue;
}
// ...rest of class...
}
InteractionMode 是一个枚举。当我尝试 运行 我的应用程序时,出现以下异常:
System.TypeInitializationException: 'The type initializer for 'MyApp.CanvasMapControl' threw an exception.'
Inner Exception
ArgumentException: The parameter is incorrect. createDefaultValueCallback
我尝试过的事情:
- 将 DependencyProperty 更改为 int 并强制转换
- 为 PropertyMetadata 传递 null
- 为 PropertyMetadata 的默认值传递 null
- 传递函数而不是默认值的值
无论我尝试什么,在启动时它总是针对 ActiveInteractionMode 的 SetValue 行抛出上述异常。我错过了什么使它不起作用?
更新:InteractionModeInternal 是一个简单的私有 属性,用于允许我在处理过程中临时更改 ActiveInteractionMode
private InteractionMode _interactionModeInternal;
private InteractionMode InteractionModeInternal
{
get => _interactionModeInternal;
set
{
_interactionModeInternal = value;
OnInteractionModeInternalChanged(value);
}
}
private void OnInteractionModeInternalChanged(InteractionMode interactionMode)
{
Log.Debug($"InternalInteractionMode changed to {interactionMode}");
}
除了它向控制台记录一个字符串外,我目前没有任何逻辑驱动它。
更新2:经过进一步调试,我发现启动时崩溃的原因是我在XAML中将值绑定到这些属性。注释掉这些绑定后,应用程序能够启动,但随后尝试访问 ActiveInteractionMode 的 Get 或 Set 将导致与 createDefaultValueCallback 发生相同的错误。
我已经通过你提供的段代码编写了一个示例。我试图重现你的问题。但是这个问题并没有出现在我的项目中。我已经将 code sample 上传到 github。请检查。下面的代码是自定义控件,大家可以对照下面的代码看看是不是你的项目有问题。
public enum InteractionMode
{
None,
Initiative,
Passive
}
public sealed partial class CustomUserControl : UserControl
{
public CustomUserControl()
{
this.InitializeComponent();
}
public InteractionMode ActiveInteractionMode
{
get { return (InteractionMode)GetValue(ActiveInteractionModeProperty); }
set { SetValue(ActiveInteractionModeProperty, value); }
}
public static readonly DependencyProperty ActiveInteractionModeProperty =
DependencyProperty.Register("ActiveInteractionMode", typeof(InteractionMode), typeof(CustomUserControl), new PropertyMetadata(InteractionMode.None, CanvasMapControl_InteractionModeChanged));
private static void CanvasMapControl_InteractionModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (args.OldValue != args.NewValue)
{
((CustomUserControl)obj).InteractionModeInternal = (InteractionMode)args.NewValue;
}
}
private InteractionMode _interactionModeInternal;
private InteractionMode InteractionModeInternal
{
get
{
return _interactionModeInternal;
}
set
{
_interactionModeInternal = value;
OnInteractionModeInternalChanged(value);
}
}
private void OnInteractionModeInternalChanged(InteractionMode interactionMode)
{
System.Diagnostics.Debug.WriteLine($"InternalInteractionMode changed to {interactionMode}");
}
以防将来有人遇到此问题,我将其作为答案发布,因为它确定了我遇到的具体问题。我不知道我是否做错了什么,或者这是否是 UWP 或我的 phone 中的错误,但我不再有此代码,因此无法进一步调试。
Update 2: After further debugging, I have found the reason the crash
happens on startup is that I was binding values to these properties in
XAML. After commenting out those bindings, the application was able to
startup, but then attempting to access either the Get or Set for
ActiveInteractionMode would cause this same error with
createDefaultValueCallback to occur.
我在 UWP 应用程序中有以下代码:
public sealed partial class CanvasMapControl : UserControl
{
public static readonly DependencyProperty ActiveInteractionModeProperty =
DependencyProperty.Register(nameof(ActiveInteractionMode),
typeof(InteractionMode),
typeof(CanvasMapControl),
new PropertyMetadata(InteractionMode.None, CanvasMapControl_InteractionModeChanged));
public InteractionMode ActiveInteractionMode {
get => (InteractionMode)GetValue(ActiveInteractionModeProperty);
set => SetValue(ActiveInteractionModeProperty, value);
}
private static void CanvasMapControl_InteractionModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
((CanvasMapControl)obj).InteractionModeInternal = (InteractionMode)args.NewValue;
}
// ...rest of class...
}
InteractionMode 是一个枚举。当我尝试 运行 我的应用程序时,出现以下异常:
System.TypeInitializationException: 'The type initializer for 'MyApp.CanvasMapControl' threw an exception.'
Inner Exception
ArgumentException: The parameter is incorrect. createDefaultValueCallback
我尝试过的事情:
- 将 DependencyProperty 更改为 int 并强制转换
- 为 PropertyMetadata 传递 null
- 为 PropertyMetadata 的默认值传递 null
- 传递函数而不是默认值的值
无论我尝试什么,在启动时它总是针对 ActiveInteractionMode 的 SetValue 行抛出上述异常。我错过了什么使它不起作用?
更新:InteractionModeInternal 是一个简单的私有 属性,用于允许我在处理过程中临时更改 ActiveInteractionMode
private InteractionMode _interactionModeInternal;
private InteractionMode InteractionModeInternal
{
get => _interactionModeInternal;
set
{
_interactionModeInternal = value;
OnInteractionModeInternalChanged(value);
}
}
private void OnInteractionModeInternalChanged(InteractionMode interactionMode)
{
Log.Debug($"InternalInteractionMode changed to {interactionMode}");
}
除了它向控制台记录一个字符串外,我目前没有任何逻辑驱动它。
更新2:经过进一步调试,我发现启动时崩溃的原因是我在XAML中将值绑定到这些属性。注释掉这些绑定后,应用程序能够启动,但随后尝试访问 ActiveInteractionMode 的 Get 或 Set 将导致与 createDefaultValueCallback 发生相同的错误。
我已经通过你提供的段代码编写了一个示例。我试图重现你的问题。但是这个问题并没有出现在我的项目中。我已经将 code sample 上传到 github。请检查。下面的代码是自定义控件,大家可以对照下面的代码看看是不是你的项目有问题。
public enum InteractionMode
{
None,
Initiative,
Passive
}
public sealed partial class CustomUserControl : UserControl
{
public CustomUserControl()
{
this.InitializeComponent();
}
public InteractionMode ActiveInteractionMode
{
get { return (InteractionMode)GetValue(ActiveInteractionModeProperty); }
set { SetValue(ActiveInteractionModeProperty, value); }
}
public static readonly DependencyProperty ActiveInteractionModeProperty =
DependencyProperty.Register("ActiveInteractionMode", typeof(InteractionMode), typeof(CustomUserControl), new PropertyMetadata(InteractionMode.None, CanvasMapControl_InteractionModeChanged));
private static void CanvasMapControl_InteractionModeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
{
if (args.OldValue != args.NewValue)
{
((CustomUserControl)obj).InteractionModeInternal = (InteractionMode)args.NewValue;
}
}
private InteractionMode _interactionModeInternal;
private InteractionMode InteractionModeInternal
{
get
{
return _interactionModeInternal;
}
set
{
_interactionModeInternal = value;
OnInteractionModeInternalChanged(value);
}
}
private void OnInteractionModeInternalChanged(InteractionMode interactionMode)
{
System.Diagnostics.Debug.WriteLine($"InternalInteractionMode changed to {interactionMode}");
}
以防将来有人遇到此问题,我将其作为答案发布,因为它确定了我遇到的具体问题。我不知道我是否做错了什么,或者这是否是 UWP 或我的 phone 中的错误,但我不再有此代码,因此无法进一步调试。
Update 2: After further debugging, I have found the reason the crash happens on startup is that I was binding values to these properties in XAML. After commenting out those bindings, the application was able to startup, but then attempting to access either the Get or Set for ActiveInteractionMode would cause this same error with createDefaultValueCallback to occur.