C# why null after casting
Hi everyone pleas help me i so confused why my code has a null after casting this is the xaml code i have
<Window.Resources>
<Style x:Key="Menu" TargetType="{x:Type Border}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Width" Value="25" />
<EventSetter Event="MouseLeftButtonUp" Handler="Menu_MouseLeftButtonUp" />
</Style>
</Window.Resources>
<Grid>
<Border Name="BorderCloseWindow" CornerRadius="0,8,0,0"
Style="{StaticResource Menu}">
<Image Source="pack://application:,,,/images/icons/CloseSTD.png" />
</Border>
</Grid>
and this the C# that handle the border
private void Menu_MouseLeftButtonUp(object sender, RoutedEventArgs e)
{
Border b = e.Source as Border;
if (b.Name == "BorderCloseWindow")
{
th开发者_运维百科is.Close();
}
}
and if i mouse button down in the border that will give error like this Object reference not set to an instance of an object. that happen in
if(b.Name == "BorderCloseWindow")
please help me why that give null? and how to repair my program so can run.
Apparently, e.Source
is not of type Border
.
The first thing you should fix is your cast. You are using
Border b = e.Source as Border;
which returns null
if e.Source
is not a Border, leading to a subsequent NullReferenceException. Since you are not checking for null afterwards, you should use a normal cast:
Border b = (Border)e.Source;
This won't fix your underlying problem, but it will make sure that
- you get the correct exception for the underlying problem (an
InvalidCastException
rather than aNullReferenceException
) and - the error is thrown in the line that is really the cause of the problem (rather than the following
if
, which is entirely innocent).
Now the second thing, the source of your problem: RoutedEventsArgs.Source
is not the border that you attached your event handler to (i.e., it's not the control handling the event). It's the control that raised the event, which is probably the image inside the border. See the documentation of RoutedEventArgs.Source for details.
Thus, to fix this problem, use the sender instead of e.Source
:
Border b = (Border)sender;
Probably sender will be Border
, try to cast sender as Border first:
Border b = sender as Border;
If it will not help, just set breakpoint within handler, than open watch window and you will see actual types of sender
and e.Source
.
First, that's how as
behaves when the cast doesn't succeed. It is made this way so that you can easily check whether it did or not. If you wrote
Border b = (Border)e.Source;
it would throw InvalidCastException
.
Second, e.Source
contains the object that you actually clicked on, in this case, the Image
. If you want to access the objects that is handling the event, use the sender
parameter.
So your code should look like this:
private void Menu_MouseLeftButtonUp(object sender, RoutedEventArgs e)
{
Border b = (Border)sender;
if (b.Name == "BorderCloseWindow")
{
this.Close();
}
}
Or even better, just
private void Menu_MouseLeftButtonUp(object sender, RoutedEventArgs e)
{
this.Close();
}
This would work if set different handler method for each Control
you want to handle some event for. It is much less fragile: it will still work if you change the name of the Border
(you don't even need to have it named) and if you accidentally change the name of the method either in XAML or C#, you most likely get a compile-time error.
It appears e.Source is not a Border so e.Source as Border is null. Source may be another object inside the border, with the event routed to the border.
you can try to test the type of e.Source with
if (e.Source is Border)
{
}
or you could get your border object by casting sender instead of e.Source.
Change your code to look like this:
private void Menu_MouseLeftButtonUp(object sender, RoutedEventArgs e)
{
System.Diagnostics.Debug.WriteLine(
"Sender contains an object of type {0}",
sender.GetType());
System.Diagnostics.Debug.WriteLine(
"e.Source contains an object of type {0}",
e.Source.GetType());
}
When you trigger the event, the information you need will be written to the Output Window. You may need to make this visible using the View menu of Visual Studio. Then you will be able to see what is going on and sort it out yourself.
e.Source is an object of type image.
So you need to cast the sender as Border.
Border b = sender as Border;
精彩评论