WPF - isEnabled 上的 NullReferenceException
我是 WPF 新手,过去我使用过 Windows 窗体。我在这里遇到一个问题,我希望有人向我解释。下面是一个非常简单的例子。
我有一个 XAML 页面,其中有一个复选框、一个按钮和一个文本字段。默认情况下该复选框处于选中状态。
当取消选中该复选框时,我想启用按钮和文本字段,例如
private void UseDefaultFoldersCB_Checked(object sender, RoutedEventArgs e)
{
//MessageBox.Show("");
if (StartDirLocationTB.IsEnabled == false)
{
StartDirLocationTB.IsEnabled = true;
}
if (SelectStartLocationBtn.IsEnabled == false)
{
SelectStartLocationBtn.IsEnabled = true;
}
}
XAML:
<CheckBox Content="Use Default Folders" IsChecked="True" Height="16" HorizontalAlignment="Left" Margin="10,14,0,0" Name="UseDefaultFoldersCB" VerticalAlignment="Top" Checked="UseDefaultFoldersCB_Checked" />
<TextBox Height="23" IsEnabled="False" HorizontalAlignment="Left" Margin="9,38,0,0" Name="StartDirLocationTB" VerticalAlignment="Top" Width="403" Background="WhiteSmoke" />
<Button Content="Select Start Folder" IsEnabled="False" Height="23" HorizontalAlignment="Right" Margin="0,38,6,0" Name="SelectStartLocationBtn" VerticalAlignment="Top" Width="139" />
堆栈跟踪:
System.NullReferenceException 是 未由用户代码处理
消息=对象引用未设置为 对象的实例。
来源=TestProject StackTrace: 在 TestProject.MainWindow.UseDefaultFoldersCB_Checked(对象 发送者、RoatedEventArgs e) 中 C:\Users\jc\Desktop\Test\TestProject\MainWindow.xaml.cs:line 611 在 System.Windows.EventRoute.InvokeHandlersImpl(对象 源、RoatedEventArgs 参数、布尔值 重新加注) 在 System.Windows.UIElement.RaiseEventImpl(DependencyObject 发送者、RoatedEventArgs 参数) 在 System.Windows.Controls.Primitives.ToggleButton.OnIsCheckedChanged(DependencyObject d、DependencyPropertyChangedEventArgs e) 在 System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 在 System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs e) 在 System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs 参数) 在 System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex 条目索引、依赖属性 dp、 PropertyMetadata 元数据, 有效值条目旧条目, 有效值输入&新条目,布尔值 coerceWithDeferredReference,布尔值 coerceWithCurrentValue、操作类型 操作类型) 在 System.Windows.DependencyObject.SetValueCommon(DependencyProperty dp、对象值、PropertyMetadata 元数据、布尔值 coerceWithDeferredReference,布尔值 coerceWithCurrentValue、操作类型 操作类型,布尔值是内部) 在 System.Windows.DependencyObject.SetValue(DependencyProperty dp,对象值) 在 MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(对象 inst、XamlMember 属性、对象 值)
当我从 Visual Studio 启动应用程序时,我在上述代码中收到 NullReferenceException。为什么这段代码会在应用程序启动时执行?我以为它只会在选中/取消选中复选框时执行?为什么会出现 NullReferenceException?
谢谢。
I'm new to WPF, in the past I've used Windows Forms. I'm having an issue here that I like someone to explain to me. The below is a really simple example.
I've got a XAML page on which I've got a single checkbox, a button, and a text field. The checkbox is checked by default.
When the checkbox is unchecked, I want to enable the button and the text field, e.g.
private void UseDefaultFoldersCB_Checked(object sender, RoutedEventArgs e)
{
//MessageBox.Show("");
if (StartDirLocationTB.IsEnabled == false)
{
StartDirLocationTB.IsEnabled = true;
}
if (SelectStartLocationBtn.IsEnabled == false)
{
SelectStartLocationBtn.IsEnabled = true;
}
}
XAML:
<CheckBox Content="Use Default Folders" IsChecked="True" Height="16" HorizontalAlignment="Left" Margin="10,14,0,0" Name="UseDefaultFoldersCB" VerticalAlignment="Top" Checked="UseDefaultFoldersCB_Checked" />
<TextBox Height="23" IsEnabled="False" HorizontalAlignment="Left" Margin="9,38,0,0" Name="StartDirLocationTB" VerticalAlignment="Top" Width="403" Background="WhiteSmoke" />
<Button Content="Select Start Folder" IsEnabled="False" Height="23" HorizontalAlignment="Right" Margin="0,38,6,0" Name="SelectStartLocationBtn" VerticalAlignment="Top" Width="139" />
Stack Trace:
System.NullReferenceException was
unhandled by user code
Message=Object reference not set to an
instance of an object.
Source=TestProject StackTrace:
at TestProject.MainWindow.UseDefaultFoldersCB_Checked(Object
sender, RoutedEventArgs e) in
C:\Users\jc\Desktop\Test\TestProject\MainWindow.xaml.cs:line
611
at System.Windows.EventRoute.InvokeHandlersImpl(Object
source, RoutedEventArgs args, Boolean
reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject
sender, RoutedEventArgs args)
at System.Windows.Controls.Primitives.ToggleButton.OnIsCheckedChanged(DependencyObject
d, DependencyPropertyChangedEventArgs
e)
at System.Windows.DependencyObject.OnPropertyChanged(DependencyPropertyChangedEventArgs
e)
at System.Windows.FrameworkElement.OnPropertyChanged(DependencyPropertyChangedEventArgs
e)
at System.Windows.DependencyObject.NotifyPropertyChange(DependencyPropertyChangedEventArgs
args)
at System.Windows.DependencyObject.UpdateEffectiveValue(EntryIndex
entryIndex, DependencyProperty dp,
PropertyMetadata metadata,
EffectiveValueEntry oldEntry,
EffectiveValueEntry& newEntry, Boolean
coerceWithDeferredReference, Boolean
coerceWithCurrentValue, OperationType
operationType)
at System.Windows.DependencyObject.SetValueCommon(DependencyProperty
dp, Object value, PropertyMetadata
metadata, Boolean
coerceWithDeferredReference, Boolean
coerceWithCurrentValue, OperationType
operationType, Boolean isInternal)
at System.Windows.DependencyObject.SetValue(DependencyProperty
dp, Object value)
at MS.Internal.Xaml.Runtime.ClrObjectRuntime.SetValue(Object
inst, XamlMember property, Object
value)
When I launch the application from Visual Studio, I get a NullReferenceException on the above code. Why does this code execute when the application launches? I'd have thought it would only execute when the checkbox is checked/unchecked? Why the NullReferenceException?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
答案是停止编码,就像在 WinForms 中一样。请改用数据绑定。我在这里为您找到了一个很好的示例。如果您仍想在事件处理程序中执行此操作,请将其保留在“Checked”事件中并仅添加空检查。如果您使用 Click 事件,键盘快捷键将不起作用。空值检查示例:
The answer is to stop coding as if you are in WinForms. Use Databinding instead. I found a nice sample for you here. If you still want to do it in event handlers, keep it in the 'Checked' event and just add null checks. If you use the Click event, keyboard shortcuts won't work. Null-checking sample:
您收到此事件处理程序调用的原因是因为在初始化 Page 时,XAML 解析器发现一个事件附加到 Checkbox 的 Checked 属性(即,当复选框 IsChecked 属性为 true 时将调用此事件),因此它是在加载本身时调用该事件。
我建议您使用复选框的 Click 事件,这样只要复选框状态更改,您就可以有一个事件。
所以你的 XAML 将会是这样的。
并且事件处理程序代码保持相同..
The Reason why you are receiving call on this Event Handler is because while initializing the Page , XAML pareser sees that an Event is attached to Checked attribute of the Checkbox(i.e. this event will be called when ever checkbox IsChecked property is true) thus it is calling the event at the time of loading itself.
I will suggest that you use Click event of the checkbox, so that you can have an event whenever checkbox state is changed.
So you XAML will be something Like this.
and the Eventhandler code remains same as..
XAML 中的属性设置器将导致引发与这些属性更改相关的事件,就像它们是在代码中设置的一样(或多或少)。我相信此时 XAML 解析器通过 IsChecked="True" 设置属性,事件处理程序将触发 - 并且此时 XAML 中定义的其他对象尚未实例化。
(顺便说一句,这是 Silverlight 和 WPF 在细节上往往有所不同的地方之一)。
Property setters in XAML will cause events related to those properties changing to be raised, as if they were set in code (more or less). I believe at the point the XAML parser sets the property via your IsChecked="True", the event handler fires - and at that point your other objects defined in XAML have not been instantiated.
(Incidentally this is one of those places where Silverlight and WPF tend to differ in details).
我认为 WPF 中的 XAML 解析器不能保证附加不同属性和事件处理程序的顺序。我认为在您的情况下,它首先附加您的
UseDefaultFoldersCB_Checked
处理程序,然后将IsChecked
设置为 true 来触发事件。您可以通过在发生异常时提供调用堆栈来扩展您的问题。
I do not think XAML parser in WPF guarantees the order in which different properties and event handlers will be attached. I think in your case first of all it attaches your
UseDefaultFoldersCB_Checked
handler and then setsIsChecked
to true which fires an event.You can expand your question a bit by providing call stack when exception occurs.