【问题标题】:How to get the size and location of a cell in dataGrid in WPF C#如何在 WPF C# 中的 dataGrid 中获取单元格的大小和位置
【发布时间】:2019-04-19 14:39:15
【问题描述】:

我已经开始在 WPF 中使用 dataGrid,但是来自 WinForm,它与我习惯的有点不同..

我现在的问题是我需要获取特定单元格的矩形(以便我可以访问它的大小和位置)。

在WinForm的datagrid里面有个方法叫:

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

但是,我似乎在 WPF 中找不到类似的东西,而且与我以前在 WinForm 中可以做的相比,我在网上能找到的所有东西都非常复杂..

如果可能,我想避免使用任何 XAML 代码,并全部用 C# 代码编写

希望你们中的某个人能解决我的问题。

【问题讨论】:

  • 这是 WPF 的一个不同寻常的目标。如果您不介意我问,为什么需要单元格的大小和位置?
  • 我需要能够在单元格顶部放置控件(组合框、按钮等),以便看起来控件位于单元格本身内,而我可以制作 WinForm控件的大小和位置等于单元格的大小和位置。
  • @Anthony 在 WPF 中,您可能会更改单元格的模板,这样您就可以在模板中进行控制,并将其正确放置在单元格中。
  • @Anthony,我认为在 WPF 控件中默认采用整个单元格大小。无论如何购买,您都可以在 WPF 中使用styles and templates 来执行此操作,例如通过CellTemplate。手动查找和更改单元格不是 WPF 方式。

标签: c# wpf visual-studio wpfdatagrid


【解决方案1】:

WPF 不适用于坐标,而是容器。如果您想在 DataGridCell 中放入一些内容,请找到它并将新内容放入 DataGridCell.Content 中。

在我的示例中,您可以输入行号和列号,然后按执行代码按钮。这将在所需位置的网格中放置一个按钮。点击 Click Me 后,按钮消失,显示旧单元格内容。

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

虽然这可行,但它有点像 hack。如果数据网格重新创建其内容,您的按钮将丢失。例如,如果用户单击列标题对网格进行排序,就会发生这种情况。

如果您真的需要单元格的尺寸,您可以使用 cell.ActualWidth 和 cell.ActualHeight 获得。但是这些值可能随时更改,例如当用户更改列的宽度时。 WPF 中不使用坐标。如果您需要定义控件的确切位置,请使用它的 Margin 来定位它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多