MouseEvent не пузырится - PullRequest
       20

MouseEvent не пузырится

3 голосов
/ 02 августа 2011

У меня есть два пересекающихся прямоугольника.Я хочу, чтобы прозрачность обоих изменится, когда на них наведет мышь.Это работает, когда мышь находится над одним из них.Но когда мышь находится в области пересечения прямоугольников, только верхний прямоугольник меняет свою непрозрачность.Подскажите, пожалуйста, как я могу получить оба прямоугольника для изменения непрозрачности в этом случае?

<Window x:Class="WpfTestApp.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:WpfTestApp="clr-namespace:WpfTestApp" Title="MainWindow" Height="350" Width="525" >
<Window.Resources>
    <Style x:Key="RectangleHighlighter" TargetType="{x:Type Rectangle}">
        <Setter Property="Opacity" Value="0.25" />
        <Style.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Opacity" Value="1" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

    <Grid x:Name="LayoutRoot">
        <Rectangle Stroke="Black" Width="100" Fill="Green" Height="1000" Margin="0,15,0,0" Style="{StaticResource RectangleHighlighter}"/>
        <Rectangle Stroke="Black" Width="1000" Fill="Green" Height="100" Margin="0,15,0,0" Style="{StaticResource RectangleHighlighter}"/>
    </Grid>
</Window>

Ответы [ 3 ]

2 голосов
/ 02 августа 2011

На самом деле аналогичный подход, который описал HiTech Magic:

<Window.Resources>
    <Style x:Key="RectangleHighlighter" TargetType="{x:Type Rectangle}">
        <Setter Property="Opacity" Value="0.25" />
        <Style.Triggers>
            <Trigger Property="Tag" Value="MouseOver">
                <Setter Property="Opacity" Value="1" />
            </Trigger>
        </Style.Triggers>
    </Style>
</Window.Resources>

<Grid x:Name="LayoutRoot" Background="Transparent" MouseMove="LayoutRoot_MouseMove">
    <Rectangle Stroke="Black" Width="100" Fill="Green" Height="1000" Margin="0,15,0,0" Style="{StaticResource RectangleHighlighter}"/>
    <Rectangle Stroke="Black" Width="1000" Fill="Green" Height="100" Margin="0,15,0,0" Style="{StaticResource RectangleHighlighter}"/>
</Grid>

И его код:

    private List<DependencyObject> hitResultsList = new List<DependencyObject>();

    private void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
    {
        // Retrieve the coordinate of the mouse position.
        Point pt = e.GetPosition((UIElement)sender);

        // Clear the contents of the list used for hit test results.
        hitResultsList.Clear();

        // Set up a callback to receive the hit test result enumeration.
        VisualTreeHelper.HitTest(LayoutRoot, null,
            new HitTestResultCallback(MyHitTestResult),
            new PointHitTestParameters(pt));

        // Unset all children
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(LayoutRoot); ++i)
        {
            var element = VisualTreeHelper.GetChild(LayoutRoot, i) as FrameworkElement;
            if (element != null)
            {
                element.Tag = null;
            }
        }

        // Perform actions on the hit test results list.
        foreach (var dependencyObject in hitResultsList)
        {
            var element = dependencyObject as FrameworkElement;
            if (element != null)
            {
                element.Tag = "MouseOver";
            }
        }
    }

    // Return the result of the hit test to the callback.
    public HitTestResultBehavior MyHitTestResult(HitTestResult result)
    {
        // Add the hit test result to the list that will be processed after the enumeration.
        hitResultsList.Add(result.VisualHit);

        // Set the behavior to return visuals at all z-order levels.
        return HitTestResultBehavior.Continue;
    }

Конечно, для этого случая лучше добавить некоторые специальные свойства и поведения.

1 голос
/ 02 августа 2011

Вместо этого вам нужно добавить обработчик наведения на родительскую сетку, сделать так, чтобы у обоих прямоугольников было IsHitTestVisible = False и использовать VisualTreeHelper.FindElementsInHostCoordinates , чтобы определить, какой объект фактически находился под мышью (1 или более).

Если вам нужно, чтобы он основывался на стилях, предложение Марио Вернари сработает, но наведение будет срабатывать в любом месте сетки, а не только над прямоугольниками.

Это кажется мне очень полезной идеей для привязанного поведения. Поведение будет реализовывать код, описанный выше, но будет вызывать события наведения на дочерних объектах, так что вы все равно сможете делать это с помощью стилей ... придется попробовать.

0 голосов
/ 02 августа 2011

Попробуйте применить стиль к элементу Grid.

...