原因の 1 つは、パネルの背景が設定されていないことです。
背景を設定しない場合、コントロールは「その領域は処理されません」と見なされ、描画されないため実質的に透明になります。ただし、より多くの結果があります。その領域は描画されないだけでなく、追跡されません (マウス イベントなど)。
手始めに、Background="Transparent" を設定してみてください。すでに透明であるため、ほとんど意味がないかもしれませんが、このように Panel コントロールには背景があり、他に問題がなければ、すぐにマウス イベントを認識し始める可能性があります。
編集:簡単な例:
UserControl.xaml
<UserControl x:Class="UserControlMouse.MyButtonPanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
Background="LightBlue"
Tag="You will never see this message">
<StackPanel Margin="20" Background="LightGray"
MouseEnter="handler_MouseEnter" MouseMove="handler_MouseMove" MouseLeave="handler_MouseLeave"
Tag="StackPanel">
<StackPanel.Resources>
<Style TargetType="Border">
<Setter Property="Margin" Value="2" />
<Setter Property="Padding" Value="5" />
<Setter Property="Background" Value="Gray" />
</Style>
<Style TargetType="TextBlock">
<Setter Property="TextAlignment" Value="Center" />
<Setter Property="Background" Value="WhiteSmoke" />
</Style>
</StackPanel.Resources>
<Button Content="#1" MaxWidth="80" Tag="Button#1" />
<Button Content="#2" MaxWidth="80" Tag="Button#2"
MouseEnter="handler_MouseEnter" MouseMove="handler_MouseMove" MouseLeave="handler_MouseLeave"
/>
<Button Content="#3" MaxWidth="80" Tag="Button#3" />
<Button Content="#4" MaxWidth="80" Tag="Button#4" />
<Button Content="#5" MaxWidth="80" Tag="Button#5"
MouseEnter="handler_MouseEnter" MouseMove="handler_MouseMove" MouseLeave="handler_MouseLeave"
/>
<Button Content="#6" MaxWidth="80" Tag="Button#6" />
<Button Content="#7" MaxWidth="80" Tag="Button#7" />
<Button Content="#8" MaxWidth="80" Tag="Button#8" />
<TextBlock Margin="0,20,0,0" Tag="Comment TextBlock #1">
<Run Text="Sender was: " />
<Run Text="{Binding ReportingControl}" />
</TextBlock>
<TextBlock Tag="Comment TextBlock #2">
<Run Text="Source was: " />
<Run Text="{Binding ContainerControl}" />
</TextBlock>
<TextBlock Tag="Comment TextBlock #3">
<Run Text="Now you are in: " />
<Run Text="{Binding ControlUnderMouse}" />
</TextBlock>
<UniformGrid Columns="3" Tag="indicator UniformGrid">
<Border Visibility="{Binding Visib_OnEnter}" Tag="indicator border #1">
<TextBlock Text="Enter" />
</Border>
<Border Visibility="{Binding Visib_OnMove}" Tag="indicator border #2"
MouseEnter="handler_MouseEnter" MouseMove="handler_MouseMove" MouseLeave="handler_MouseLeave">
<TextBlock Text="Move" />
</Border>
<Border Visibility="{Binding Visib_OnLeave}" Tag="indicator border #3">
<TextBlock Text="Leave" />
</Border>
</UniformGrid>
</StackPanel>
</UserControl>
usercontrol.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace UserControlMouse
{
public partial class MyButtonPanel : UserControl
{
private SimpleDataObject theData = new SimpleDataObject();
public MyButtonPanel()
{
InitializeComponent();
this.DataContext = theData;
}
private const int COUNTER_LAG = 20;
private int counter_enter = 0;
private void handler_MouseEnter(object sender, MouseEventArgs e)
{
counter_enter = counter_mouse;
theData.Visib_OnEnter = System.Windows.Visibility.Visible;
theData.Visib_OnMove = System.Windows.Visibility.Hidden;
theData.Visib_OnLeave = System.Windows.Visibility.Hidden;
theData.ReportingControl = makeDescriptionOfControl(sender);
theData.ContainerControl = makeDescriptionOfControl(e.Source);
theData.ControlUnderMouse = makeDescriptionOfControl(null);
}
private int counter_mouse = 0;
private void handler_MouseMove(object sender, MouseEventArgs e)
{
++counter_mouse;
if (counter_mouse > counter_enter + COUNTER_LAG) theData.Visib_OnEnter = System.Windows.Visibility.Hidden;
theData.Visib_OnMove = System.Windows.Visibility.Visible;
if (counter_mouse > counter_leave + COUNTER_LAG) theData.Visib_OnLeave = System.Windows.Visibility.Hidden;
theData.ReportingControl = makeDescriptionOfControl(sender);
theData.ContainerControl = makeDescriptionOfControl(e.Source);
theData.ControlUnderMouse = makeDescriptionOfControl(null);
}
private int counter_leave = 0;
private void handler_MouseLeave(object sender, MouseEventArgs e)
{
counter_leave = counter_mouse;
theData.Visib_OnEnter = System.Windows.Visibility.Hidden;
theData.Visib_OnMove = System.Windows.Visibility.Hidden;
theData.Visib_OnLeave = System.Windows.Visibility.Visible;
theData.ReportingControl = makeDescriptionOfControl(sender);
theData.ContainerControl = makeDescriptionOfControl(e.Source);
theData.ControlUnderMouse = makeDescriptionOfControl(null);
}
private string makeDescriptionOfControl(object uiobj)
{
if (uiobj == null)
return "???";
string text = uiobj.GetType().Name;
var fe = uiobj as FrameworkElement;
if (fe != null && fe.Tag != null)
text += " (" + (string)((FrameworkElement)uiobj).Tag + ")";
return text;
}
}
public class SimpleDataObject : DependencyObject
{
public string ControlUnderMouse { get { return (string)GetValue(ControlUnderMouseProperty); } set { SetValue(ControlUnderMouseProperty, value); } }
public static readonly DependencyProperty ControlUnderMouseProperty = DependencyProperty.Register("ControlUnderMouse", typeof(string), typeof(SimpleDataObject), new UIPropertyMetadata("???"));
public string ReportingControl { get { return (string)GetValue(ReportingControlProperty); } set { SetValue(ReportingControlProperty, value); } }
public static readonly DependencyProperty ReportingControlProperty = DependencyProperty.Register("ReportingControl", typeof(string), typeof(SimpleDataObject), new UIPropertyMetadata("???"));
public string ContainerControl { get { return (string)GetValue(ContainerControlProperty); } set { SetValue(ContainerControlProperty, value); } }
public static readonly DependencyProperty ContainerControlProperty = DependencyProperty.Register("ContainerControl", typeof(string), typeof(SimpleDataObject), new UIPropertyMetadata("???"));
public Visibility Visib_OnEnter { get { return (Visibility)GetValue(Visib_OnEnterProperty); } set { SetValue(Visib_OnEnterProperty, value); } }
public static readonly DependencyProperty Visib_OnEnterProperty = DependencyProperty.Register("Visib_OnEnter", typeof(Visibility), typeof(SimpleDataObject), new UIPropertyMetadata(Visibility.Hidden));
public Visibility Visib_OnMove { get { return (Visibility)GetValue(Visib_OnMoveProperty); } set { SetValue(Visib_OnMoveProperty, value); } }
public static readonly DependencyProperty Visib_OnMoveProperty = DependencyProperty.Register("Visib_OnMove", typeof(Visibility), typeof(SimpleDataObject), new UIPropertyMetadata(Visibility.Hidden));
public Visibility Visib_OnLeave { get { return (Visibility)GetValue(Visib_OnLeaveProperty); } set { SetValue(Visib_OnLeaveProperty, value); } }
public static readonly DependencyProperty Visib_OnLeaveProperty = DependencyProperty.Register("Visib_OnLeave", typeof(Visibility), typeof(SimpleDataObject), new UIPropertyMetadata(Visibility.Hidden));
}
}
サンプルウィンドウ
<Window x:Class="UserControlMouse.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:UserControlMouse"
Title="MainWindow" Height="350" Width="525">
<Grid Background="Red">
<my:MyButtonPanel Margin="10" />
</Grid>
</Window>
実行して遊んでください。
- イベントがどのように発生し、どのコントロールがイベントを認識しているかを観察します。SENDER と SOURCE がどのように変化しているかに注意してください
- SENDER は常に同じであり、マウス キャプチャのルートであることに注意してください。変化するのはソース
- ボタン #2 とボタン #5 のみが ENTER/LEAVE を報告していることに注意してください(これらにはダイレクト ハンドラーがありますが、他にはありません!)
- 他のコントロールは、マウス ハンドラーがなくても、マウス移動で「検出可能」であることに注意してください。マウス キャプチャ セットを持たないソースでイベントを取得できます。
- OriginalSource (最後のテキスト行) を確認してください - これはマウスのすぐ下にあるコントロールです - 多くの場合、これはいくつかのテンプレートまたはスタイルからの「リーフ コントロール」であるため、注意したいコントロールではありません。