views:

283

answers:

2

Once the added button in grid(window control Grid, not Gridview or datagrid) is clicked, how to find which row and column the button is located in the grid event handler, like click event or some other events? Not the button click event handler

        #region Grid event handler setup
        myGrid.MouseEnter += new MouseEventHandler(myGrid_MouseEnter);
        myGrid.MouseLeave += new MouseEventHandler(myGrid_MouseLeave);
        myGrid.MouseDown += new MouseButtonEventHandler(myGrid_MouseDown);
        myGrid.MouseUp += new MouseButtonEventHandler(myGrid_MouseUp);
        #endregion

Thanks

I notice that Boyan has some solution for the button click event handler case

http://stackoverflow.com/questions/363100/in-wpf-how-can-i-determine-what-column-row-in-a-grid-a-control-is

In the Click event handler for the button you say:

int row; 
Button btn = sender as Button; 
if (btn != null) 
{ 
    row = Grid.GetRow(btn); // And you have the row number... 
} 
else 
{ 
    // A nasty error occurred... 
}
+2  A: 

See InputHitTest():

UIelement element = (UIelement) Grid.InputHitTest(e.GetPosition(Grid));
row= Grid.GetRow(element); 
BlueRaja - Danny Pflughoeft
It will not return the row or column number anyway.
Archie
Cool! Thanks a lot!
UIelement element = (UIelement )Grid.InputHitTest(e.GetPosition(Grid)); row= Grid.GetRow(element);
A: 

As with just about everything else in WPF, it's probably better to use data binding.

You can build a class for the buttons and bind the ItemsSource to a collection of them instead of using an XmlDataProvider; I'm using XML because it makes for an example you can easily copy and paste:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
  <Page.Resources>
    <XmlDataProvider x:Key="Data">
      <x:XData>
        <Data xmlns="">
          <Button Row="0" Column="0" Text="First"/>
          <Button Row="1" Column="3" Text="Second"/>
          <Button Row="4" Column="4" Text="Third"/>
        </Data>
      </x:XData>
    </XmlDataProvider>
  </Page.Resources>
  <DockPanel Height="300" Width="300">
    <ItemsControl ItemsSource="{Binding Source={StaticResource Data}, XPath=/Data/Button}">
       <ItemsControl.ItemTemplate>
        <DataTemplate>
         <Grid>
          <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
          </Grid.RowDefinitions>
          <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>            
          </Grid.ColumnDefinitions>
           <Button Grid.Row="{Binding XPath=@Row}" 
                   Grid.Column="{Binding XPath=@Column}" 
                   Content="{Binding XPath=@Text}"
                   Click="Button_Click"/>
         </Grid>
        </DataTemplate>
       </ItemsControl.ItemTemplate>
    </ItemsControl>
  </DockPanel>
</Page>

The event handler should look like this (untested, since I wrote the above in Kaxaml):

private void Button_Click(object sender, EventArgs e)
{
   Button b = (Button) sender;
   XmlElement elm = (XmlElement)b.DataContext;
   int row = Convert.ToInt32(elm.GetAttribute("Row"));
   int column = Convert.ToInt32(elm.GetAttribute("Column"));
   // now do whatever you need to do with the row and column
}

The key here is that the button's DataContext contains all of the information that you'll use for the Click event - row and column, sure, but also any other properties that you need to associate with the button. The more you work with an approach like this, the less WPF-specific code and markup you'll end up writing.

Robert Rossney