ValidationRule ValidatesOnTargetUpdated NullReferenceException 在设计时 [英] ValidationRule ValidatesOnTargetUpdated NullReferenceException at Design Time
问题描述
我正在尝试编写一个 ValidationRule 来检查字符串是否为空:
I am trying to write a ValidationRule that checks if a string is null:
public class NotNullValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
string str = value as string;
return string.IsNullOrEmpty(str) ? new ValidationResult(false, Application.Current.FindResource("EmptyStringNotAllowed")) : ValidationResult.ValidResult;
}
}
在我的窗口中,我是这样使用它的:
In my Window I am using it like this:
<TextBox
Name="TxtDescription"
Width="Auto"
controls:TextBoxHelper.Watermark="{DynamicResource Description}">
<TextBox.Text>
<Binding Path="MachineToEdit.Description">
<Binding.ValidationRules>
<validation:NotNullValidationRule ValidatesOnTargetUpdated="True"/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
如果我启动设计器,我会得到这个 NullReferenceException:
If I start the Designer I get this NullReferenceException:
at System.Windows.Data.BindingExpression.RunValidationRule(ValidationRule validationRule, Object value, CultureInfo culture)
at System.Windows.Data.BindingExpression.ValidateOnTargetUpdated()
at System.Windows.Data.BindingExpression.TransferValue(Object newValue, Boolean isASubPropertyChange)
at System.Windows.Data.BindingExpression.Activate(Object item)
at System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt attempt)
at System.Windows.Data.BindingExpression.MS.Internal.Data.IDataBindEngineClient.AttachToContext(Boolean lastChance)
at MS.Internal.Data.DataBindEngine.Task.Run(Boolean lastChance)
at MS.Internal.Data.DataBindEngine.Run(Object arg)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.DispatcherOperation.InvokeImpl()
at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at MS.Internal.CulturePreservingExecutionContext.Run(CulturePreservingExecutionContext executionContext, ContextCallback callback, Object state)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.ProcessQueue()
at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
at System.Windows.Application.RunDispatcher(Object ignore)
at System.Windows.Application.RunInternal(Window window)
at System.Windows.Application.Run(Window window)
at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.DesignerProcess.RunApplication()
at Microsoft.VisualStudio.DesignTools.DesignerContract.Isolation.DesignerProcess.<>c__DisplayClass5_0.<Main>b__0()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
为什么会这样?如果我不激活 ValidatesOnTargetUpdated 它正在工作.但是我必须在窗口加载时进行验证.
Why does this happen? If I dont activate ValidatesOnTargetUpdated it is working. But I have to validate when the window is loading.
感谢您的所有回答,祝您有美好的一天.
Thank you for all answers and have a nice day.
推荐答案
比代码隐藏更好的答案
在 VS2017 中,在 XAML 编辑器中启用项目代码也为我修复了它.
In VS2017, enabling project code in the XAML editor also fixed it for me.
--- 上一个答案---
--- Previous answer ---
我遇到了同样的问题,不幸的是 Thomas V 的回答没有奏效.通过将 ValidationRules 添加到代码隐藏中,我能够解决这个问题.也许不是最理想的方法,但确实解决了问题.
I was having the same issue and Thomas V's answer unfortunately did not work. I was able to fix the issue by moving the addition of the ValidationRules to the codebehind. Perhaps not the most ideal method, but it did correct the issue.
您也可以考虑在 Thomas V 的设计师检查中包装代码隐藏逻辑,但它对我来说没有这些.
You could also look at wrapping the codebehind logic in Thomas V's designer check, but it worked without that for me.
XAML:
<TextBox x:Name="FirstNameTextBox">
<TextBox.Text>
<Binding x:Name="FirstNameTextBoxBinding"
Path="TheNewUser.TheNewUser.GivenName"
UpdateSourceTrigger="PropertyChanged"
Mode="TwoWay"
NotifyOnValidationError="True"
Delay="500" />
</TextBox.Text>
</TextBox>
代码隐藏:
public NewUserWizard_Info_View()
{
InitializeComponent();
Loaded += TriggerValidationOnLoaded;
FirstNameTextBoxBinding.ValidationRules.Add(new ValidateEmptyOrNull()
{
ValidatesOnTargetUpdated = true
});
}
private void TriggerValidationOnLoaded(object obj, RoutedEventArgs e)
{
// This is needed to trigger the validation on first load
FirstNameTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}
这篇关于ValidationRule ValidatesOnTargetUpdated NullReferenceException 在设计时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!