2013-07-22 3 views
0

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

+1

Вы можете использовать 'Mouse.DirectlyOver как FrameworkElement', но я уверен, что вы используете неправильный подход для начала. Отправьте соответствующий код и XAML. –

ответ

1

Первое, что нужно помнить о том, что управление с прозрачным фоном не создает события для своих прозрачных областей. Либо установите цвет нужной сетки, либо привяжите ее к цвету фона окна, в котором находится сетка, или события не будут срабатывать.

Этот образец кода демонстрирует вычислительный метод определения местоположения элемента сетки с учетом события MouseMove. Аргументы события ButtonClick очень похожи. Соответствующие методы из этого образца: ColumnComputation и RowComputation, которые занимают позицию в определении контроля и определения столбцов или строк для линейного анализа. Образец работает на элементе U12 InnerGrid.

Форма Класс:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    } 



    private void InnerGrid_PreviewMouseMove(object sender, MouseEventArgs e) 
    { 
     this.XCoordinate.Text = e.GetPosition(InnerGrid).X.ToString(); 
     this.YCoordinate.Text = e.GetPosition(InnerGrid).Y.ToString(); 
     this.ColumnPosition.Text = ColumnComputation(InnerGrid.ColumnDefinitions, e.GetPosition(InnerGrid).X).ToString(); 
     this.RowPosition.Text = RowComputation(InnerGrid.RowDefinitions, e.GetPosition(InnerGrid).Y).ToString(); 

    } 

    private double ColumnComputation(ColumnDefinitionCollection c, double YPosition) 
    { 
     var columnLeft = 0.0; var columnCount = 0; 
     foreach (ColumnDefinition cd in c) 
     { 
      double actWidth = cd.ActualWidth; 
      if (YPosition >= columnLeft && YPosition < (actWidth + columnLeft)) return columnCount; 
      columnCount++; 
      columnLeft += cd.ActualWidth; 
     } 
     return (c.Count + 1); 
    } 
    private double RowComputation(RowDefinitionCollection r, double XPosition) 
    { 
     var rowTop = 0.0; var rowCount = 0; 
     foreach (RowDefinition rd in r) 
     { 
      double actHeight = rd.ActualHeight; 
      if (XPosition >= rowTop && XPosition < (actHeight + rowTop)) return rowCount; 
      rowCount++; 
      rowTop += rd.ActualHeight; 
     } 
     return (r.Count + 1); 
    } 
} 

XAML Форма:

<Window x:Name="window" x:Class="GridHitTest.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Grid Name="OuterBorder" > 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
      <ColumnDefinition/> 
     </Grid.ColumnDefinitions> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="20"/> 
      <RowDefinition Height="20"/> 
      <RowDefinition Height="*"/> 
     </Grid.RowDefinitions> 
     <TextBlock Grid.Column="0" HorizontalAlignment="Center" >X Coordinate</TextBlock> 
     <TextBlock Grid.Column="1" HorizontalAlignment="Center" >Y Coordinate</TextBlock> 
     <TextBlock Grid.Column="2" HorizontalAlignment="Center" >Column</TextBlock> 
     <TextBlock Grid.Column="3" HorizontalAlignment="Center" >Row</TextBlock> 
     <TextBlock Grid.Row="1" Grid.Column="0" HorizontalAlignment="Center" Name="XCoordinate">kjahsd</TextBlock> 
     <TextBlock Grid.Row="1" Grid.Column="1" HorizontalAlignment="Center" Name="YCoordinate">___ahsdjf</TextBlock> 
     <TextBlock Grid.Row="1" Grid.Column="2" HorizontalAlignment="Center" Name="ColumnPosition">___ahsdjf</TextBlock> 
     <TextBlock Grid.Row="1" Grid.Column="3" HorizontalAlignment="Center" Name="RowPosition">___ahsdjf</TextBlock> 
     <Grid Name="InnerGrid" Margin="20,45,20,10" Grid.ColumnSpan="4" Grid.RowSpan="3" Background="{Binding Background, ElementName=window}" PreviewMouseMove="InnerGrid_PreviewMouseMove" > 
      <Grid.RowDefinitions> 
       <RowDefinition/> 
       <RowDefinition/> 
       <RowDefinition/> 
      </Grid.RowDefinitions> 
      <Grid.ColumnDefinitions> 
       <ColumnDefinition/> 
       <ColumnDefinition/> 
       <ColumnDefinition/> 
      </Grid.ColumnDefinitions> 
     </Grid> 
    </Grid> 
</Window> 
1

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

private void OnButtonClick(object sender, RoutedEventArgs e) 
{ 
    var buttonClicked = sender as Button; 

    var gridRow = (int)buttonClicked.GetValue(MyGrid.RowProperty); 
    var gridColumn = (int)buttonClicked.GetValue(MyGrid.ColumnProperty); 

} 
0

Вот еще один вариант, который кажется намного проще, чем предложил правильный ответ.

private void Grid_MouseDown(object sender, MouseButtonEventArgs e) 
{ 
    var element = (UIElement)e.Source; 
    int row = Grid.GetRow(element); 
    int column = Grid.GetColumn(element); 
} 
Смежные вопросы