2011-06-14 85 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;