How to get the size and location of a cell in dataGrid in WPF C#












0















I've started to work with a dataGrid in WPF, but coming from WinForm, its a little different from what I'm used to..



My problem right now is that i need to get a specific cell's rectangle (so I can access its size & location).



In WinForm's datagrid there where a method called:



cellRectangle = dataGridView.GetCellDisplayRectangle(columnIndex, rowIndex, cutOverflow)


However, I cant seem to find anything like this in WPF, and everything i can find online is massivly complicated compared to what i used to be able to do in WinForm..



If possible, I would like to avoid any XAML code, and write it all in C# code



Hope someone of you have a solution to my problem.










share|improve this question


















  • 2





    That's an unusual goal for WPF. Why do you need the size and location of a cell, if you don't mind me asking?

    – icebat
    Nov 16 '18 at 13:11











  • I need to be able to place controls (comboBoxes, buttons, etc.) on top of the cell, so that it looks like the control is within the cell itself, and i WinForm I could just make the control's size and location equal to the cells size and location.

    – Anthony
    Nov 16 '18 at 13:50








  • 1





    @Anthony In WPF you can likely change the template of a cell so you can make your contols in the template and it would place it in the cell correctly.

    – EpicKip
    Nov 16 '18 at 14:09






  • 2





    @Anthony, I think in WPF controls take the whole cell size by default. Buy in any case, you can use styles and templates to do this in WPF, for example via CellTemplate. Finding and changing the cells manually is not the WPF way.

    – icebat
    Nov 16 '18 at 14:14
















0















I've started to work with a dataGrid in WPF, but coming from WinForm, its a little different from what I'm used to..



My problem right now is that i need to get a specific cell's rectangle (so I can access its size & location).



In WinForm's datagrid there where a method called:



cellRectangle = dataGridView.GetCellDisplayRectangle(columnIndex, rowIndex, cutOverflow)


However, I cant seem to find anything like this in WPF, and everything i can find online is massivly complicated compared to what i used to be able to do in WinForm..



If possible, I would like to avoid any XAML code, and write it all in C# code



Hope someone of you have a solution to my problem.










share|improve this question


















  • 2





    That's an unusual goal for WPF. Why do you need the size and location of a cell, if you don't mind me asking?

    – icebat
    Nov 16 '18 at 13:11











  • I need to be able to place controls (comboBoxes, buttons, etc.) on top of the cell, so that it looks like the control is within the cell itself, and i WinForm I could just make the control's size and location equal to the cells size and location.

    – Anthony
    Nov 16 '18 at 13:50








  • 1





    @Anthony In WPF you can likely change the template of a cell so you can make your contols in the template and it would place it in the cell correctly.

    – EpicKip
    Nov 16 '18 at 14:09






  • 2





    @Anthony, I think in WPF controls take the whole cell size by default. Buy in any case, you can use styles and templates to do this in WPF, for example via CellTemplate. Finding and changing the cells manually is not the WPF way.

    – icebat
    Nov 16 '18 at 14:14














0












0








0








I've started to work with a dataGrid in WPF, but coming from WinForm, its a little different from what I'm used to..



My problem right now is that i need to get a specific cell's rectangle (so I can access its size & location).



In WinForm's datagrid there where a method called:



cellRectangle = dataGridView.GetCellDisplayRectangle(columnIndex, rowIndex, cutOverflow)


However, I cant seem to find anything like this in WPF, and everything i can find online is massivly complicated compared to what i used to be able to do in WinForm..



If possible, I would like to avoid any XAML code, and write it all in C# code



Hope someone of you have a solution to my problem.










share|improve this question














I've started to work with a dataGrid in WPF, but coming from WinForm, its a little different from what I'm used to..



My problem right now is that i need to get a specific cell's rectangle (so I can access its size & location).



In WinForm's datagrid there where a method called:



cellRectangle = dataGridView.GetCellDisplayRectangle(columnIndex, rowIndex, cutOverflow)


However, I cant seem to find anything like this in WPF, and everything i can find online is massivly complicated compared to what i used to be able to do in WinForm..



If possible, I would like to avoid any XAML code, and write it all in C# code



Hope someone of you have a solution to my problem.







c# wpf visual-studio wpfdatagrid






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 16 '18 at 11:51









AnthonyAnthony

336




336








  • 2





    That's an unusual goal for WPF. Why do you need the size and location of a cell, if you don't mind me asking?

    – icebat
    Nov 16 '18 at 13:11











  • I need to be able to place controls (comboBoxes, buttons, etc.) on top of the cell, so that it looks like the control is within the cell itself, and i WinForm I could just make the control's size and location equal to the cells size and location.

    – Anthony
    Nov 16 '18 at 13:50








  • 1





    @Anthony In WPF you can likely change the template of a cell so you can make your contols in the template and it would place it in the cell correctly.

    – EpicKip
    Nov 16 '18 at 14:09






  • 2





    @Anthony, I think in WPF controls take the whole cell size by default. Buy in any case, you can use styles and templates to do this in WPF, for example via CellTemplate. Finding and changing the cells manually is not the WPF way.

    – icebat
    Nov 16 '18 at 14:14














  • 2





    That's an unusual goal for WPF. Why do you need the size and location of a cell, if you don't mind me asking?

    – icebat
    Nov 16 '18 at 13:11











  • I need to be able to place controls (comboBoxes, buttons, etc.) on top of the cell, so that it looks like the control is within the cell itself, and i WinForm I could just make the control's size and location equal to the cells size and location.

    – Anthony
    Nov 16 '18 at 13:50








  • 1





    @Anthony In WPF you can likely change the template of a cell so you can make your contols in the template and it would place it in the cell correctly.

    – EpicKip
    Nov 16 '18 at 14:09






  • 2





    @Anthony, I think in WPF controls take the whole cell size by default. Buy in any case, you can use styles and templates to do this in WPF, for example via CellTemplate. Finding and changing the cells manually is not the WPF way.

    – icebat
    Nov 16 '18 at 14:14








2




2





That's an unusual goal for WPF. Why do you need the size and location of a cell, if you don't mind me asking?

– icebat
Nov 16 '18 at 13:11





That's an unusual goal for WPF. Why do you need the size and location of a cell, if you don't mind me asking?

– icebat
Nov 16 '18 at 13:11













I need to be able to place controls (comboBoxes, buttons, etc.) on top of the cell, so that it looks like the control is within the cell itself, and i WinForm I could just make the control's size and location equal to the cells size and location.

– Anthony
Nov 16 '18 at 13:50







I need to be able to place controls (comboBoxes, buttons, etc.) on top of the cell, so that it looks like the control is within the cell itself, and i WinForm I could just make the control's size and location equal to the cells size and location.

– Anthony
Nov 16 '18 at 13:50






1




1





@Anthony In WPF you can likely change the template of a cell so you can make your contols in the template and it would place it in the cell correctly.

– EpicKip
Nov 16 '18 at 14:09





@Anthony In WPF you can likely change the template of a cell so you can make your contols in the template and it would place it in the cell correctly.

– EpicKip
Nov 16 '18 at 14:09




2




2





@Anthony, I think in WPF controls take the whole cell size by default. Buy in any case, you can use styles and templates to do this in WPF, for example via CellTemplate. Finding and changing the cells manually is not the WPF way.

– icebat
Nov 16 '18 at 14:14





@Anthony, I think in WPF controls take the whole cell size by default. Buy in any case, you can use styles and templates to do this in WPF, for example via CellTemplate. Finding and changing the cells manually is not the WPF way.

– icebat
Nov 16 '18 at 14:14












1 Answer
1






active

oldest

votes


















0














WPF does not work with coordinates, but containers. If you want to put something into a DataGridCell, find it and put the new content in DataGridCell.Content.



In my sample, you can enter row and column number, then press Execute Code Button. This will place a button into the grid at the desired location. After clicking on Click Me, the button disappears and the old cell content is shown.



enter image description here



<Window x:Class="DataGridCell.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DataGridCell"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<DockPanel>
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Background="LightGray">
<Label Content="Row:"/>
<TextBox Name="RowTextBox" Text="2"/>
<Label Content="Column:"/>
<TextBox Name="ColumnTextBox" Text="1"/>
<Button DockPanel.Dock="Bottom" Content="Execute Code" Name="ExecuteButton"/>
</StackPanel>
<DataGrid Name="MainDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" >
<DataGrid.Columns>
<DataGridTextColumn Header="Col0" Binding="{Binding Col0}"/>
<DataGridTextColumn Header="Col1" Binding="{Binding Col1}" />
<DataGridTextColumn Header="Col2" Binding="{Binding Col2}" />
</DataGrid.Columns>
</DataGrid>
</DockPanel>
</Window>


using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;

namespace DataGridCell {

public class RowData {
public string Col0 { get; set; }
public string Col1 { get; set; }
public string Col2 { get; set; }
}

public partial class MainWindow: Window {
public MainWindow() {
InitializeComponent();
var dataList = new List<RowData>();
dataList.Add(new RowData {Col0="0.0", Col1="0.1", Col2="0.2"});
dataList.Add(new RowData {Col0="1.0", Col1="1.1", Col2="1.2"});
dataList.Add(new RowData {Col0="2.0", Col1="2.1", Col2="2.2"});
dataList.Add(new RowData {Col0="3.0", Col1="3.1", Col2="3.2"});
ObservableCollection<RowData> custdata = new ObservableCollection<RowData>(dataList);
MainDataGrid.DataContext = custdata;
ExecuteButton.Click+=ExecuteButton_Click;
}

ContentControl cell;
object oldContent;

private void ExecuteButton_Click(object sender, RoutedEventArgs e) {
var row = int.Parse(RowTextBox.Text);
var col = int.Parse(ColumnTextBox.Text);
var cellContent = (FrameworkElement)MainDataGrid.Columns[col].GetCellContent(MainDataGrid.Items[row]);
cell = (ContentControl)cellContent.Parent;
var button = new Button {Content="Click me" };
button.Click += Button_Click;
oldContent = cell.Content;
cell.Content = button;
ExecuteButton.IsEnabled = false;
}

private void Button_Click(object sender, RoutedEventArgs e) {
cell.Content = oldContent;
ExecuteButton.IsEnabled = true;
}
}
}


While this works, it is a bit of a hack. If the datagrid recreates its content, your button will be lost. This can happen for example, if the user clicks on a column head to sort the grid.



If you REALLY need the dimension of the cell, you can get it with cell.ActualWidth and cell.ActualHeight. But these values might change any time, for example when the user changes the width of the column. Coordinates are not used in WPF. If you need to define the exact place of your control, use it's Margin to position it.






share|improve this answer


























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53337323%2fhow-to-get-the-size-and-location-of-a-cell-in-datagrid-in-wpf-c-sharp%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    0














    WPF does not work with coordinates, but containers. If you want to put something into a DataGridCell, find it and put the new content in DataGridCell.Content.



    In my sample, you can enter row and column number, then press Execute Code Button. This will place a button into the grid at the desired location. After clicking on Click Me, the button disappears and the old cell content is shown.



    enter image description here



    <Window x:Class="DataGridCell.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:DataGridCell"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
    <DockPanel>
    <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Background="LightGray">
    <Label Content="Row:"/>
    <TextBox Name="RowTextBox" Text="2"/>
    <Label Content="Column:"/>
    <TextBox Name="ColumnTextBox" Text="1"/>
    <Button DockPanel.Dock="Bottom" Content="Execute Code" Name="ExecuteButton"/>
    </StackPanel>
    <DataGrid Name="MainDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" >
    <DataGrid.Columns>
    <DataGridTextColumn Header="Col0" Binding="{Binding Col0}"/>
    <DataGridTextColumn Header="Col1" Binding="{Binding Col1}" />
    <DataGridTextColumn Header="Col2" Binding="{Binding Col2}" />
    </DataGrid.Columns>
    </DataGrid>
    </DockPanel>
    </Window>


    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Windows;
    using System.Windows.Controls;

    namespace DataGridCell {

    public class RowData {
    public string Col0 { get; set; }
    public string Col1 { get; set; }
    public string Col2 { get; set; }
    }

    public partial class MainWindow: Window {
    public MainWindow() {
    InitializeComponent();
    var dataList = new List<RowData>();
    dataList.Add(new RowData {Col0="0.0", Col1="0.1", Col2="0.2"});
    dataList.Add(new RowData {Col0="1.0", Col1="1.1", Col2="1.2"});
    dataList.Add(new RowData {Col0="2.0", Col1="2.1", Col2="2.2"});
    dataList.Add(new RowData {Col0="3.0", Col1="3.1", Col2="3.2"});
    ObservableCollection<RowData> custdata = new ObservableCollection<RowData>(dataList);
    MainDataGrid.DataContext = custdata;
    ExecuteButton.Click+=ExecuteButton_Click;
    }

    ContentControl cell;
    object oldContent;

    private void ExecuteButton_Click(object sender, RoutedEventArgs e) {
    var row = int.Parse(RowTextBox.Text);
    var col = int.Parse(ColumnTextBox.Text);
    var cellContent = (FrameworkElement)MainDataGrid.Columns[col].GetCellContent(MainDataGrid.Items[row]);
    cell = (ContentControl)cellContent.Parent;
    var button = new Button {Content="Click me" };
    button.Click += Button_Click;
    oldContent = cell.Content;
    cell.Content = button;
    ExecuteButton.IsEnabled = false;
    }

    private void Button_Click(object sender, RoutedEventArgs e) {
    cell.Content = oldContent;
    ExecuteButton.IsEnabled = true;
    }
    }
    }


    While this works, it is a bit of a hack. If the datagrid recreates its content, your button will be lost. This can happen for example, if the user clicks on a column head to sort the grid.



    If you REALLY need the dimension of the cell, you can get it with cell.ActualWidth and cell.ActualHeight. But these values might change any time, for example when the user changes the width of the column. Coordinates are not used in WPF. If you need to define the exact place of your control, use it's Margin to position it.






    share|improve this answer






























      0














      WPF does not work with coordinates, but containers. If you want to put something into a DataGridCell, find it and put the new content in DataGridCell.Content.



      In my sample, you can enter row and column number, then press Execute Code Button. This will place a button into the grid at the desired location. After clicking on Click Me, the button disappears and the old cell content is shown.



      enter image description here



      <Window x:Class="DataGridCell.MainWindow"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:local="clr-namespace:DataGridCell"
      mc:Ignorable="d"
      Title="MainWindow" Height="450" Width="800">
      <DockPanel>
      <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Background="LightGray">
      <Label Content="Row:"/>
      <TextBox Name="RowTextBox" Text="2"/>
      <Label Content="Column:"/>
      <TextBox Name="ColumnTextBox" Text="1"/>
      <Button DockPanel.Dock="Bottom" Content="Execute Code" Name="ExecuteButton"/>
      </StackPanel>
      <DataGrid Name="MainDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" >
      <DataGrid.Columns>
      <DataGridTextColumn Header="Col0" Binding="{Binding Col0}"/>
      <DataGridTextColumn Header="Col1" Binding="{Binding Col1}" />
      <DataGridTextColumn Header="Col2" Binding="{Binding Col2}" />
      </DataGrid.Columns>
      </DataGrid>
      </DockPanel>
      </Window>


      using System.Collections.Generic;
      using System.Collections.ObjectModel;
      using System.Windows;
      using System.Windows.Controls;

      namespace DataGridCell {

      public class RowData {
      public string Col0 { get; set; }
      public string Col1 { get; set; }
      public string Col2 { get; set; }
      }

      public partial class MainWindow: Window {
      public MainWindow() {
      InitializeComponent();
      var dataList = new List<RowData>();
      dataList.Add(new RowData {Col0="0.0", Col1="0.1", Col2="0.2"});
      dataList.Add(new RowData {Col0="1.0", Col1="1.1", Col2="1.2"});
      dataList.Add(new RowData {Col0="2.0", Col1="2.1", Col2="2.2"});
      dataList.Add(new RowData {Col0="3.0", Col1="3.1", Col2="3.2"});
      ObservableCollection<RowData> custdata = new ObservableCollection<RowData>(dataList);
      MainDataGrid.DataContext = custdata;
      ExecuteButton.Click+=ExecuteButton_Click;
      }

      ContentControl cell;
      object oldContent;

      private void ExecuteButton_Click(object sender, RoutedEventArgs e) {
      var row = int.Parse(RowTextBox.Text);
      var col = int.Parse(ColumnTextBox.Text);
      var cellContent = (FrameworkElement)MainDataGrid.Columns[col].GetCellContent(MainDataGrid.Items[row]);
      cell = (ContentControl)cellContent.Parent;
      var button = new Button {Content="Click me" };
      button.Click += Button_Click;
      oldContent = cell.Content;
      cell.Content = button;
      ExecuteButton.IsEnabled = false;
      }

      private void Button_Click(object sender, RoutedEventArgs e) {
      cell.Content = oldContent;
      ExecuteButton.IsEnabled = true;
      }
      }
      }


      While this works, it is a bit of a hack. If the datagrid recreates its content, your button will be lost. This can happen for example, if the user clicks on a column head to sort the grid.



      If you REALLY need the dimension of the cell, you can get it with cell.ActualWidth and cell.ActualHeight. But these values might change any time, for example when the user changes the width of the column. Coordinates are not used in WPF. If you need to define the exact place of your control, use it's Margin to position it.






      share|improve this answer




























        0












        0








        0







        WPF does not work with coordinates, but containers. If you want to put something into a DataGridCell, find it and put the new content in DataGridCell.Content.



        In my sample, you can enter row and column number, then press Execute Code Button. This will place a button into the grid at the desired location. After clicking on Click Me, the button disappears and the old cell content is shown.



        enter image description here



        <Window x:Class="DataGridCell.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataGridCell"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
        <DockPanel>
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Background="LightGray">
        <Label Content="Row:"/>
        <TextBox Name="RowTextBox" Text="2"/>
        <Label Content="Column:"/>
        <TextBox Name="ColumnTextBox" Text="1"/>
        <Button DockPanel.Dock="Bottom" Content="Execute Code" Name="ExecuteButton"/>
        </StackPanel>
        <DataGrid Name="MainDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" >
        <DataGrid.Columns>
        <DataGridTextColumn Header="Col0" Binding="{Binding Col0}"/>
        <DataGridTextColumn Header="Col1" Binding="{Binding Col1}" />
        <DataGridTextColumn Header="Col2" Binding="{Binding Col2}" />
        </DataGrid.Columns>
        </DataGrid>
        </DockPanel>
        </Window>


        using System.Collections.Generic;
        using System.Collections.ObjectModel;
        using System.Windows;
        using System.Windows.Controls;

        namespace DataGridCell {

        public class RowData {
        public string Col0 { get; set; }
        public string Col1 { get; set; }
        public string Col2 { get; set; }
        }

        public partial class MainWindow: Window {
        public MainWindow() {
        InitializeComponent();
        var dataList = new List<RowData>();
        dataList.Add(new RowData {Col0="0.0", Col1="0.1", Col2="0.2"});
        dataList.Add(new RowData {Col0="1.0", Col1="1.1", Col2="1.2"});
        dataList.Add(new RowData {Col0="2.0", Col1="2.1", Col2="2.2"});
        dataList.Add(new RowData {Col0="3.0", Col1="3.1", Col2="3.2"});
        ObservableCollection<RowData> custdata = new ObservableCollection<RowData>(dataList);
        MainDataGrid.DataContext = custdata;
        ExecuteButton.Click+=ExecuteButton_Click;
        }

        ContentControl cell;
        object oldContent;

        private void ExecuteButton_Click(object sender, RoutedEventArgs e) {
        var row = int.Parse(RowTextBox.Text);
        var col = int.Parse(ColumnTextBox.Text);
        var cellContent = (FrameworkElement)MainDataGrid.Columns[col].GetCellContent(MainDataGrid.Items[row]);
        cell = (ContentControl)cellContent.Parent;
        var button = new Button {Content="Click me" };
        button.Click += Button_Click;
        oldContent = cell.Content;
        cell.Content = button;
        ExecuteButton.IsEnabled = false;
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
        cell.Content = oldContent;
        ExecuteButton.IsEnabled = true;
        }
        }
        }


        While this works, it is a bit of a hack. If the datagrid recreates its content, your button will be lost. This can happen for example, if the user clicks on a column head to sort the grid.



        If you REALLY need the dimension of the cell, you can get it with cell.ActualWidth and cell.ActualHeight. But these values might change any time, for example when the user changes the width of the column. Coordinates are not used in WPF. If you need to define the exact place of your control, use it's Margin to position it.






        share|improve this answer















        WPF does not work with coordinates, but containers. If you want to put something into a DataGridCell, find it and put the new content in DataGridCell.Content.



        In my sample, you can enter row and column number, then press Execute Code Button. This will place a button into the grid at the desired location. After clicking on Click Me, the button disappears and the old cell content is shown.



        enter image description here



        <Window x:Class="DataGridCell.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DataGridCell"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
        <DockPanel>
        <StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Background="LightGray">
        <Label Content="Row:"/>
        <TextBox Name="RowTextBox" Text="2"/>
        <Label Content="Column:"/>
        <TextBox Name="ColumnTextBox" Text="1"/>
        <Button DockPanel.Dock="Bottom" Content="Execute Code" Name="ExecuteButton"/>
        </StackPanel>
        <DataGrid Name="MainDataGrid" ItemsSource="{Binding}" AutoGenerateColumns="False" >
        <DataGrid.Columns>
        <DataGridTextColumn Header="Col0" Binding="{Binding Col0}"/>
        <DataGridTextColumn Header="Col1" Binding="{Binding Col1}" />
        <DataGridTextColumn Header="Col2" Binding="{Binding Col2}" />
        </DataGrid.Columns>
        </DataGrid>
        </DockPanel>
        </Window>


        using System.Collections.Generic;
        using System.Collections.ObjectModel;
        using System.Windows;
        using System.Windows.Controls;

        namespace DataGridCell {

        public class RowData {
        public string Col0 { get; set; }
        public string Col1 { get; set; }
        public string Col2 { get; set; }
        }

        public partial class MainWindow: Window {
        public MainWindow() {
        InitializeComponent();
        var dataList = new List<RowData>();
        dataList.Add(new RowData {Col0="0.0", Col1="0.1", Col2="0.2"});
        dataList.Add(new RowData {Col0="1.0", Col1="1.1", Col2="1.2"});
        dataList.Add(new RowData {Col0="2.0", Col1="2.1", Col2="2.2"});
        dataList.Add(new RowData {Col0="3.0", Col1="3.1", Col2="3.2"});
        ObservableCollection<RowData> custdata = new ObservableCollection<RowData>(dataList);
        MainDataGrid.DataContext = custdata;
        ExecuteButton.Click+=ExecuteButton_Click;
        }

        ContentControl cell;
        object oldContent;

        private void ExecuteButton_Click(object sender, RoutedEventArgs e) {
        var row = int.Parse(RowTextBox.Text);
        var col = int.Parse(ColumnTextBox.Text);
        var cellContent = (FrameworkElement)MainDataGrid.Columns[col].GetCellContent(MainDataGrid.Items[row]);
        cell = (ContentControl)cellContent.Parent;
        var button = new Button {Content="Click me" };
        button.Click += Button_Click;
        oldContent = cell.Content;
        cell.Content = button;
        ExecuteButton.IsEnabled = false;
        }

        private void Button_Click(object sender, RoutedEventArgs e) {
        cell.Content = oldContent;
        ExecuteButton.IsEnabled = true;
        }
        }
        }


        While this works, it is a bit of a hack. If the datagrid recreates its content, your button will be lost. This can happen for example, if the user clicks on a column head to sort the grid.



        If you REALLY need the dimension of the cell, you can get it with cell.ActualWidth and cell.ActualHeight. But these values might change any time, for example when the user changes the width of the column. Coordinates are not used in WPF. If you need to define the exact place of your control, use it's Margin to position it.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 21 '18 at 18:19

























        answered Nov 21 '18 at 16:15









        Peter HuberPeter Huber

        1,3011523




        1,3011523
































            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53337323%2fhow-to-get-the-size-and-location-of-a-cell-in-datagrid-in-wpf-c-sharp%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Bressuire

            Vorschmack

            Quarantine