WPF 中值得注意的 IsHitTestVisible

WPF 中值得注意的 IsHitTestVisible

當此屬性設為 false 時,外觀上看起來沒有變化,但在操作上它已完全被忽略,不會觸發事件,可以直接點擊到它下面的元素。

最後更新 2021/10/20 下午6:18
普通的地球人
預計閱讀 4 分鐘
分類
WPF
標籤
.NET WPF 命中測試

這個屬性我們平時可能不太常用,先來看一下 MSDN 上的解釋:

解釋得非常專業,不過我還是沒看懂。

說說我的理解吧:把這個屬性設為 false,看起來沒有變化,但操作上已經完全忽略它了,不會觸發事件,可以直接點選到它下面的東西。

這個屬性可以方便地解決工作中常見的麻煩,例如下面的例子:

注意上面那部分。效果很簡單,就是一個漸變效果。但這個漸變貫穿兩列,處理起來就有點小麻煩。

當然解決方案有很多:

可以寫兩個 ListBoxItem 的樣式,第一個放頂部有漸變的背景,與右部保持一致,透過樣式選擇器來實現。這顯然比較麻煩。

還可以在大背景下放一個漸變,ListBoxItem 的上半部做成透明,這樣相對簡單,但不一定能實現理想效果。

IsHitTestVisible 屬性就很好地解決了這個問題。直接在上層放一個 border,背景設成漸變,IsHitTestVisible 設為 false。這樣就既能看見漸變效果,又能透過 border 直接點選到 ListBoxItem。設定一個屬性就解決了問題,非常方便。相當於在上面放了一個蒙板,但這個蒙板看得見卻點不到。

類似的我還想到一個場景:

這個效果頂層是一張圖片,IsHitTestVisible 為 false,透明度為 0.3。

並非圖片是背景,然後所有控制項都是半透明效果。

請見程式碼:

XMAL:

<Grid>
  <Grid>
    <Grid.RowDefinitions>
      <RowDefinition Height="70"></RowDefinition>
      <RowDefinition></RowDefinition>
      <RowDefinition Height="50"></RowDefinition>
    </Grid.RowDefinitions>
    <Border Background="#555F5F">
      <label Content="logo" Foreground="White"></label>
    </Border>
    <Grid Grid.Row="1" Background="#AAAFAF">
      <StackPanel
        HorizontalAlignment="Center"
        VerticalAlignment="Center"
        Button.Click="StackPanel_Click"
      >
        <button Width="132" Height="32" Content="金閃閃" Margin="10"></button>
        <button Width="132" Height="32" Content="小圓" Margin="10"></button>
      </StackPanel>
      <label
        Content="我不透明"
        Background="Green"
        Foreground="Blue"
        Width="100"
        Height="100"
        Margin="76,29,266,171"
      ></label>
      <label
        Content="我不透明"
        Background="Red"
        Foreground="Blue"
        Width="100"
        Height="40"
        Margin="112,40,230,220"
      ></label>
    </Grid>
    <Border Grid.Row="2" Background="#555F5F">
      <label Content="狀態欄" Foreground="White"></label>
    </Border>
  </Grid>
  <image
    Name="img"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    Width="0"
    Height="0"
    Source="/Image/jinshanshan.jpg"
    Stretch="Fill"
    Opacity="0.1"
    IsHitTestVisible="False"
  ></image>
</Grid>

後台:

private void StackPanel_Click(object sender, RoutedEventArgs e)
{
    Button btn = (Button)e.OriginalSource;
    string content = btn.Content.ToString();
    if (content == "金閃閃")
    {
        img.Source = new BitmapImage(new Uri(@"/Image/jinshanshan.jpg", UriKind.Relative));
    }
    if (content == "小圓")
    {
        img.Source = new BitmapImage(new Uri(@"/Image/xiaoyuan.jpg", UriKind.Relative));
    }

    DoubleAnimation daX = new DoubleAnimation();
    daX.From = 0;
    daX.To = 400;
    daX.FillBehavior = FillBehavior.HoldEnd;
    Storyboard.SetTarget(daX, img);
    Storyboard.SetTargetProperty(daX, new PropertyPath(Image.WidthProperty));
    DoubleAnimation daY = new DoubleAnimation();
    daY.From = 0;
    daY.To = 400;
    daY.FillBehavior = FillBehavior.HoldEnd;
    Storyboard.SetTarget(daY, img);
    Storyboard.SetTargetProperty(daY, new PropertyPath(Image.HeightProperty));
    DoubleAnimation daOp = new DoubleAnimation();
    daOp.From = 1;
    daOp.To = 0.3;
    daOp.FillBehavior = FillBehavior.HoldEnd;
    Storyboard.SetTarget(daOp, img);
    Storyboard.SetTargetProperty(daOp, new PropertyPath(Image.OpacityProperty));

    Storyboard sb = new Storyboard();
    sb.Children.Add(daX);
    sb.Children.Add(daY);
    sb.Children.Add(daOp);
    sb.Begin();
}
繼續探索

延伸閱讀

更多文章
同分類 / 同標籤 2025/1/26

WPF 藉助自訂 XML 檔案實現國際化

本文詳細介紹了在WPF程式中使用自訂XML檔案實現國際化的方法,包括安裝必備NuGet套件、動態獲取語言清單、動態切換語言、在程式碼和XAML介面中使用翻譯字串等內容,同時提供了原始碼連結,幫助開發者輕鬆實現WPF應用程式的國際化。

繼續閱讀