3

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?

Zarkos
  • 457
  • 10
  • 30

2 Answers2

2

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.

Robert
  • 2,222
  • 2
  • 21
  • 36
  • So idd calculating the width of a cell :) Thx – Zarkos Jun 20 '12 at 11:31
  • 1
    @Hmm, you are assuming that Grid is equispaced among its cells. – WPF-it Jun 20 '12 at 11:57
  • @AngelWPF you can just apply to x and y, for instance, x=Math.Floor(x/width) or y/width etc... – Robert Jun 20 '12 at 13:37
  • I think what @AngelWPF is trying to say is that you are assuming that the cells will have equal width and heights (through division)... that's never the case in a typical `Grid`. –  Jun 20 '12 at 13:50
  • well, in my case my grid has equal widths & heights. I'm using my Grid as a square where I can move Controls inside. But the controls need to snap to the Row & Column where I drop them... – Zarkos Jun 20 '12 at 14:55
2

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;
    }
WPF-it
  • 19,625
  • 8
  • 55
  • 71