MouseEnter/MouseLeave on RowDefinition
I want to do this:
https://github.com/rails/rails/commit/f50aeda2f73b47c47664e3651c638ba624418b8b
See how, as your mouse cursor moves over the lines of source code, an image/button appears to the left of the table? That.
So I have a Grid, and RowDefinition has MouseEnter and MouseLeave events. Turns out these events are useless and can never fire (please correct me if I'm wrong here), because they require a Background property (even if it's Transparent), and RowDefinition doesn't have a Background property.
I can't just hook MouseEnter on every element in every cell, 开发者_如何学JAVAbecause by the time I've moved my mouse the newly visible button will have already disappeared.
How can I get this working?
The RowDefinitions
and ColumnDefinitions
aren't actually in the Visual Tree since they are FrameworkContentElements
(rather than FrameworkElements
) and that's why they don't raise any mouse events, they aren't Visuals
. They are just used by the Grid
to position its childs.
One approach that comes to mind is to use the Attached Events Mouse.MouseMove
and Mouse.MouseLeave
on the Grid
to get notified when these events are raised for any child in the Grid
or the Grid
itself.
<Grid Mouse.MouseMove="Grid_MouseMove"
Mouse.MouseLeave="Grid_MouseLeave"
Background="Transparent">
In the Mouse.MouseMove
event handler we can get the relative mouse position to the Grid
and calculate which RowDefinition
is currently being hoovered by the mouse and store that in an Attached Property, like 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);
}
Now we can query the Grid
for the MouseOverRowDefinition
so the rest is just a matter of comparing Grid.Row
for the Image
to MouseOverRowDefinition
for the Grid
to decide if it should be Visible
or not.
Uploaded a small sample app that does this here if you want to try it out:
http://dl.dropbox.com/u/39657172/MouseOverGridRowDefinition.zip
精彩评论