Как получить размер и расположение ячейки в dataGrid в WPF C # - PullRequest
0 голосов
/ 16 ноября 2018

Я начал работать с dataGrid в WPF, но, исходя из WinForm, он немного отличается от того, к чему я привык ..

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

В таблице данных WinForm есть метод с именем:

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

Однако в WPF я не могу найти ничего подобногои все, что я могу найти в Интернете, значительно сложнее по сравнению с тем, что я имел обыкновение делать в WinForm.

Если возможно, я бы хотел избежать любого кода XAML и написать все это в коде C #

Надеюсь, у кого-то из вас есть решение моей проблемы.

1 Ответ

0 голосов
/ 21 ноября 2018

WPF работает не с координатами, а с контейнерами. Если вы хотите поместить что-то в DataGridCell, найдите его и поместите новый контент в DataGridCell.Content.

В моем примере вы можете ввести номер строки и столбца, а затем нажать кнопку «Выполнить код». Это поместит кнопку в сетку в нужном месте. После нажатия кнопки «Нажмите меня» кнопка исчезает, и отображается содержимое старой ячейки.

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;
    }
  }
}

Хотя это работает, это что-то вроде хака. Если сетка данных воссоздает свое содержимое, ваша кнопка будет потеряна. Это может произойти, например, если пользователь щелкает заголовок столбца для сортировки сетки.

Если вам ДЕЙСТВИТЕЛЬНО нужен размер ячейки, вы можете получить его с помощью cell.ActualWidth и cell.ActualHeight. Но эти значения могут измениться в любое время, например, когда пользователь меняет ширину столбца. Координаты не используются в WPF. Если вам нужно определить точное место вашего элемента управления, используйте его Margin для его позиционирования.

...