簡體   English   中英

C# 為什么是 null 鑄造后

[英]C# why null after casting

大家好,請幫助我,我很困惑為什么我的代碼在鑄造后有一個 null 這是我的 xaml 代碼

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

如果我在邊框上按下鼠標按鈕,則會出現這樣的錯誤 Object 參考未設置為 object 的實例。 發生在

if(b.Name == "BorderCloseWindow")

請幫我為什么要給null? 以及如何修復我的程序以便可以運行。

顯然, e.Source不是Border類型。

你應該解決的第一件事是你的演員表。 您正在使用

Border b = e.Source as Border;

如果e.Source不是 Border,則返回null ,從而導致后續的 NullReferenceException。 由於之后您沒有檢查 null,因此您應該使用普通演員表:

Border b = (Border)e.Source;

這不會解決您的潛在問題,但可以確保

  • 你得到了潛在問題的正確異常(一個InvalidCastException而不是NullReferenceException )和
  • 錯誤是在真正導致問題的行中拋出的(而不是下面的if ,這完全是無辜的)。

現在第二件事,問題的根源: RoutedEventsArgs.Source不是您將事件處理程序附加到的邊界(即,它不是處理事件的控件)。 它是引發事件的控件,可能是邊框內的圖像。 有關詳細信息,請參閱RoutedEventArgs.Source 的文檔

因此,要解決此問題,請使用 sender 而不是e.Source

Border b = (Border)sender;

可能 sender 將是Border ,首先嘗試將 sender 轉換為 Border :

  Border b = sender as Border;

如果沒有幫助,只需在處理程序中設置斷點,然后打開手表 window ,您將看到sendere.Source的實際類型。

首先,這就是當演員陣容不成功時as行為方式。 它是這樣制作的,因此您可以輕松檢查它是否這樣做。 如果你寫

Border b = (Border)e.Source;

它會拋出InvalidCastException

其次, e.Source包含您實際單擊的 object,在本例中為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# 中的方法名稱,它仍然可以工作,您很可能會得到編譯時錯誤。

看來 e.Source 不是 Border 所以 e.Source as Border 是 null。 源可能是邊界內的另一個 object,事件路由到邊界。

您可以嘗試測試 e.Source 的類型

if (e.Source is Border)
{
}

或者您可以通過投射發件人而不是 e.Source 來獲得您的邊框 object。

將您的代碼更改為如下所示:

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

當您觸發事件時,您需要的信息將被寫入 Output Window。 您可能需要使用 Visual Studio 的“查看”菜單使其可見。 然后,您將能夠看到正在發生的事情並自行解決。

e.Source 是圖像類型的 object。

因此,您需要將發件人投射為 Border。

邊框 b = 作為邊框的發件人;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM