2011-06-14 68 views
3

大家好恳求帮助我,我很困惑,为什么我的代码铸造 后有一个空,这是XAML代码我有C#为什么空铸造后

<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> 

,这在C#是处理边界

private void Menu_MouseLeftButtonUp(object sender, RoutedEventArgs e) 
{ 
    Border b = e.Source as Border; 
    if (b.Name == "BorderCloseWindow") 
    { 
     this.Close(); 
    } 
} 

如果我在鼠标按钮的边框会出现这样的错误 对象引用未设置为对象的实例。 在

if(b.Name == "BorderCloseWindow") 

这种情况发生,请帮我为什么给空?以及如何修复我的程序,因此可以运行。

+0

将一个断点放在行'Border b = e.Source as Border'并查看哪个对象是事件的来源 – ChrisWue 2011-06-14 07:10:01

回答

2

看来e.Source不为Border所以e.Source AS边界为空。 源可能是边界内的另一个对象,并将事件路由到边界。

,你可以尝试用

if (e.Source is Border) 
{ 
} 

测试e.Source的类型或者你可以通过铸造发件人,而不是e.Source的让你的边框对象。

+2

C#不使用不定冠词:-) – svick 2011-06-14 07:24:05

+0

确实。我编辑了它^^ – Falanwe 2011-06-14 07:34:25

4

大概发件人会Border,尽量先投发件人为边框:

Border b = sender as Border; 

如果它不会帮助,处理程序中只需设置断点,比公开的观察窗口,你会看到的sender实际类型和e.Source

14

显然,e.Source不是Border类型。

The first thing you should fix is your cast.您正在使用

Border b = e.Source as Border; 

返回null如果e.Source不是一个边境,导致后续的NullReferenceException。既然你不检查空之后,你应该使用正常的转换:

Border b = (Border)e.Source; 

这不会解决你的根本问题,但它会确保

  • 你得到正确的例外潜在的问题(一个InvalidCastException而不是一个NullReferenceException)和
  • 错误是引发问题的原因(而不是以下if,这是完全无辜的)的行。

现在第二个事情,你的问题的根源:RoutedEventsArgs.Source你连接你的事件处理程序的边界(即,它不处理事件控制)。这是提高了事件的控制权,这可能是边界内的图像。详情请参阅the documentation of RoutedEventArgs.Source

因此,要解决此问题,使用发件人,而不是e.Source

Border b = (Border)sender; 
1

更改您的代码看起来像这样:

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()); 
} 

当您触发事件,你需要的信息将被写入到输出窗口。您可能需要使用Visual Studio的“查看”菜单使其可见。然后,你将能够看到正在发生的事情并自行整理。

+0

不只是使用断点和本地窗口更容易? – svick 2011-06-14 07:24:58

4

首先,这是as行为时,演员不成功。它是这样制作的,以便您可以轻松检查它是否有效。如果你写了

Border b = (Border)e.Source; 

它会抛出InvalidCastException

二,e.Source包含您实际点击的对象,在此例中为Image。如果要访问处理事件的对象,请使用sender参数。

所以,你的代码应该是这样的:

private void Menu_MouseLeftButtonUp(object sender, RoutedEventArgs e) 
{ 
    Border b = (Border)sender; 
    if (b.Name == "BorderCloseWindow") 
    { 
     this.Close(); 
    } 
} 

甚至更​​好,只是

private void Menu_MouseLeftButtonUp(object sender, RoutedEventArgs e) 
{ 
    this.Close(); 
} 

如果每个Control设置不同的处理方法要处理某些事件这是可行的。它不太脆弱:如果您更改Border的名称(您甚至不需要命名),并且如果意外更改了XAML或C#中的方法名称,它仍然可以工作,您很可能会得到编译时错误。

+0

@海因,谢谢你解决我的错误。 – svick 2011-06-14 19:39:16

1

e.Source是图像类型的对象。

所以你需要将发件人作为边框。

Border b = sender as Border;