MouseEnter / MouseLeave на RowDefinition - PullRequest
       5

MouseEnter / MouseLeave на RowDefinition

4 голосов
/ 09 сентября 2011

Я хочу сделать это:

https://github.com/rails/rails/commit/f50aeda2f73b47c47664e3651c638ba624418b8b

Посмотрите, как, когда курсор мыши перемещается по строкам исходного кода, изображение / кнопка появляется слева от таблицы? Это.

Итак, у меня есть Grid, а в RowDefinition есть события MouseEnter и MouseLeave. Оказывается, эти события бесполезны и никогда не могут срабатывать (пожалуйста, исправьте меня, если я здесь не прав), потому что им требуется свойство Background (даже если оно прозрачное), а RowDefinition не имеет свойства Background.

Я не могу просто подключить MouseEnter к каждому элементу в каждой ячейке, потому что к тому времени, как я переместил мышь, вновь видимая кнопка уже исчезнет.

Как мне заставить это работать?

1 Ответ

2 голосов
/ 10 сентября 2011

RowDefinitions и ColumnDefinitions на самом деле не находятся в дереве визуалов, поскольку они FrameworkContentElements (а не FrameworkElements), и поэтому они не вызывают никаких событий мыши, они не Visuals. Они просто используются Grid для позиционирования своих потомков.

Один подход, который приходит на ум, - это использовать Attached Events Mouse.MouseMove и Mouse.MouseLeave на Grid, чтобы получать уведомления, когда эти события инициируются для любого дочернего элемента в Grid или Grid.

<Grid Mouse.MouseMove="Grid_MouseMove"
      Mouse.MouseLeave="Grid_MouseLeave"
      Background="Transparent">

В обработчике события Mouse.MouseMove мы можем получить относительное положение мыши в Grid и вычислить, какое RowDefinition в данный момент копируется мышью, и сохранить его во вложенном свойстве, например MouseOverRowDefinition.

private void Grid_MouseMove(object sender, MouseEventArgs e)
{
    Grid grid = sender as Grid;
    Point mousePoint = e.GetPosition(grid);
    double heightSum = grid.RowDefinitions[0].ActualHeight;
    int activeRow = 0;
    for (; heightSum < mousePoint.Y; activeRow++)
    {
        heightSum += grid.RowDefinitions[activeRow].ActualHeight;
    }
    GridExtensions.SetMouseOverRowDefinition(grid, activeRow);
}
// No RowDefinition is beeing hoovered, set MouseOverRowDefinition to -1
private void Grid_MouseLeave(object sender, MouseEventArgs e)
{
    Grid grid = sender as Grid;
    GridExtensions.SetMouseOverRowDefinition(grid, -1);
}

Теперь мы можем запросить Grid для MouseOverRowDefinition, поэтому все остальное - просто сравнение Grid.Row для Image с MouseOverRowDefinition для Grid, чтобы решить, должно ли оно быть Visible или нет.

Загрузил небольшое примерное приложение, которое делает это здесь, если вы хотите попробовать его:
http://dl.dropbox.com/u/39657172/MouseOverGridRowDefinition.zip

...