Zarkos
Zarkos

Reputation: 457

Get Grid Row and Column from X and Y Location

I have a Grid and I know the X-value and Y-Value of where I clicked with my mouse.

Example: X: 235, Y: 235 --> This should be Column: 3 and Row: 3

How Do I get what column and Row is on that x,y coordinate?

Do I really need to add every width of the rows/columns till I get to the required x/y value?

I'm using WPF (for my grid) & c# (for the x & y position)

Can anybody help me with this?

Upvotes: 3

Views: 4535

Answers (2)

Vinit Sankhe
Vinit Sankhe

Reputation: 19885

For this please do consider ...

  1. You grid has some background color set (even Transparent will do). This is for hit test (mouse click on blank grid area) to work.
  2. GridSplitter itself is a member in the grid. This is important to know because clicking the grid splitter would also show the corresponding cell indices (Column, Row) in which the grid splitter lies.
  3. We are not concerned with ColumnSpan and RowSpan here.

XAML ...

<Window x:Class="WpfApplication3.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid Mouse.PreviewMouseDown="Grid_MouseDown"
              Background="Transparent">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>

            <GridSplitter ResizeDirection="Rows"
                          Width="{Binding ActualWidth,
                                    RelativeSource={RelativeSource
                                          AncestorType=Grid}}"
                          Height="4" Grid.ColumnSpan="3"
                          Background="Red" Grid.Row="1" />                
            <TextBox Height="60" AcceptsReturn="True" 
                     Text="Element1"
                     ScrollViewer.VerticalScrollBarVisibility="Visible" />
            <Button Content="Element2" Grid.Column="1"/>
            <TextBlock Text="Element4" Grid.Row="2" Width="100"
                       Height="40" HorizontalAlignment="Left"
                       VerticalAlignment="Center"/>
            <ComboBox SelectedIndex="0" Height="20"
                      Grid.Column="1" Grid.Row="2">
                <ComboBoxItem Content="Element5"/>
            </ComboBox>
            <CheckBox Content="Element3" Grid.Column="2"/>
            <RadioButton Content="Element6" Grid.Row="2"
                         Grid.Column="2" VerticalAlignment="Center"
                         HorizontalAlignment="Center"/>
        </Grid>
        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <TextBlock Text="Selected Column and Row is ... " Margin="5"/>
            <TextBlock x:Name="StatusTextBlock" FontSize="12"
                       FontWeight="SemiBold" Margin="5"/>
        </StackPanel>
    </Grid>
</Window>

Code Behind ..

    private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
    {
        int selectedColumnIndex = -1, selectedRowIndex = -1;
        var grid = sender as Grid;
        if (grid != null)
        {
            var pos = e.GetPosition(grid);
            var temp = pos.X;
            for (var i = 0; i < grid.ColumnDefinitions.Count; i++ )
            {
                var colDef = grid.ColumnDefinitions[i];
                temp -= colDef.ActualWidth;
                if (temp <= -1)
                {
                    selectedColumnIndex = i;
                    break;
                }
            }

            temp = pos.Y;
            for (var i = 0; i < grid.RowDefinitions.Count; i++)
            {
                var rowDef = grid.RowDefinitions[i];
                temp -= rowDef.ActualHeight;
                if (temp <= -1)
                {
                    selectedRowIndex = i;
                    break;
                }
            }
        }

        StatusTextBlock.Text = selectedColumnIndex + ", " + selectedRowIndex;
    }

Upvotes: 2

Robert
Robert

Reputation: 2282

The Math.Floor function, so for example:

Math.Floor(235/scale)
where scale is the the width or height of the grid cell.

Define: Returns the largest integer less than or equal to the specified number. Math.ceil is the opposite.

Upvotes: 2

Related Questions