WPFで注目すべきIsHitTestVisible

WPFで注目すべきIsHitTestVisible

このプロパティをfalseに設定すると、見た目は変わりませんが、操作上では完全に無視され、イベントが発生せず、直接その下の要素をクリックできるようになります。

最終更新 2021/10/20 18:18
普通的地球人
読了目安 3 分
カテゴリ
WPF
タグ
.NET WPF HitTest

この属性は普段あまり使わないかもしれませんが、まずMSDNの説明を見てみましょう。

非常に専門的に説明されていますが、私は理解できませんでした。

私の解釈を述べます。この属性を false に設定すると、見た目は変わりませんが、操作上は完全に無視され、イベントが発生せず、その下の要素を直接クリックできるようになります。

この属性は、仕事でよくある面倒な問題を簡単に解決できます。例えば、以下の例です。

上の部分に注目してください。単純なグラデーション効果です。しかし、このグラデーションが2列にまたがっているため、処理が少し厄介です。

もちろん、解決策はたくさんあります。

2つの ListBoxItem のスタイルを書き、最初のスタイルには上部にグラデーションの背景を配置し、右側と合わせてスタイルセレクタで実装する方法があります。明らかに面倒です。

大きな背景にグラデーションを配置し、ListBoxItem の上半分を透明にして、比較的簡単に実現する方法もありますが、理想的な効果が得られるとは限りません。

IsHitTestVisible 属性はこの問題をうまく解決します。上部に border を置き、背景をグラデーションに設定し、IsHitTestVisible を false に設定するだけです。これにより、グラデーション効果を見ることができ、かつ border を通して ListBoxItem を直接クリックできます。1つの属性を設定するだけで問題が解決し、非常に便利です。あたかも上にマスクをかけたような状態で、そのマスクは見えるけれどもクリックできない、という感じです。

同様のシナリオとして、次のようなものも思い浮かびました。

この効果では、最上層に画像があり、IsHitTestVisible が false、透明度が 0.3 です。

画像が背景になっているわけではなく、すべてのコントロールが半透明になっているわけでもありません。

コードを見てください。

XAML:

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

代码隐藏(C#):

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/09/13

WPF から Avalonia への移行シリーズ:なぜ WPF プログラムを Avalonia に移行しなければならないのか

過去数年間、当社の上位機ソフトウェアは主に WPF と WinForm で開発されてきました。これらの技術は Windows プラットフォームで非常に便利であり、小規模試作から現在の規模拡大による納品まで、私たちを支えてきました。しかし、ビジネスの発展や顧客ニーズの変化に伴い、単一の Windows テクノロジースタックは私たちが必ず乗り越えなければならない壁となってきました。

続きを読む
同じカテゴリ / 同じタグ 2025/01/26

WPF カスタムXMLファイルによる国際化

この記事では、WPFプログラムでカスタムXMLファイルを使用して国際化を実現する方法について詳しく説明します。必要なNuGetパッケージのインストール、言語リストの動的取得、言語の動的切り替え、コードおよびXAMLインターフェースでの翻訳文字列の使用などを含み、ソースコードのリンクも提供し、開発者がWPFアプリケーションの国際化を簡単に実装できるように支援します。

続きを読む