【问题标题】:C# WPF Data grid display error: Object being displayedC# WPF 数据网格显示错误:正在显示的对象
【发布时间】:2020-07-23 14:30:05
【问题描述】:

我已指定要在 WPF 数据网格中显示的报告列表。

作为报告对象属性的所有值都显示正常,但是报告构造函数中包含的对象的值仅显示数据网格中的通用对象名称,我不确定如何访问任何基础属性从所述对象中为用户提供更有意义的显示。

报表构造函数:

 public Report(string reporterName, Asset asset, Location incidentLocation, Room room, string incidentType)
    {
        ReporterName = reporterName;
        Asset = asset;
        IncidentLocation = incidentLocation;
        Room = room;
        IncidentType = incidentType;
    }

数据网格 XAML:

<DataGrid Name="ReportsGrid" HorizontalAlignment="Left" Height="212" Margin="33,252,0,0" VerticalAlignment="Top" Width="725"/>

使用报表对象列表设置数据网格:

List<Report> reports = new List<Report>();
reports.Add(report);

ReportsGrid.ItemsSource = reports;

Current datagrid output

任何帮助或建议将不胜感激。感谢您的宝贵时间。

【问题讨论】:

  • 如果你只是给 WPF 一个对象,它会在它上面调用 ToString(),默认情况下,它会给出类名。您可以在 xaml 绑定中显示带有点符号的属性,例如 asset.someproperty 而不仅仅是 asset。如果要显示整个对象的表示,则覆盖 ToString() 以返回所需的内容。
  • 我将在 xaml 绑定的哪个部分配置该属性?我想从资产对象中获取底层资产名称属性来显示。
  • 这些列是自动生成的还是您明确定义了 DataGridColumn?
  • 目前自动生成,如果它是我想要实现的更可取的实现,我很乐意切换。

标签: c# wpf data-binding datagrid


【解决方案1】:

当自动生成列时,它们将显示对象的ToString 方法的结果,因为无法知道如何显示自定义类型的实例。

如果您可以手动创建列,您可以为现有的列类型指定属性路径,例如DataGridTextColumn。假设Asset 有一个名为Name 的字符串属性。

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Reports}">
   <DataGrid.Columns>
      <DataGridTextColumn Header="Asset" Binding="{Binding Asset.Name}"/>
      <!-- ...other columns -->
   </DataGrid.Columns>
 </DataGrid>

如果您的数据类型更复杂,您可以改用 DataGridTemplateColumn 并创建自定义数据模板以进行显示和编辑。

<DataGridTemplateColumn Header="Asset">
   <DataGridTemplateColumn.CellTemplate>
      <DataTemplate DataType="{x:Type local:Report}">
         <TextBlock Text="{Binding Asset.Name}"/>
         <!-- ...other controls -->
      </DataTemplate>
   </DataGridTemplateColumn.CellTemplate>
   <DataGridTemplateColumn.CellEditingTemplate>
      <DataTemplate DataType="{x:Type local:Report}">
         <TextBox Text="{Binding Asset.Name}"/>
         <!-- ...other controls -->
      </DataTemplate>
   </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

如果您绝对需要自动生成列,则需要在代码隐藏或自定义行为中挂钩 AutoGeneratingColumn 事件。

<DataGrid x:Name="MyDatagrid" ItemsSource="{Binding Reports}">
MyDatagrid.AutoGeneratingColumn += OnAutoGeneratingColumns;

然后更改自动生成的列,甚至替换它们。在下面的示例中,我替换了一个列,但您也可以只使用已经生成的 e.Column,例如DataGridTextColumnset the binding in its Binding property in code 就像上面手动生成的列的示例一样。

private void OnAutoGeneratingColumns(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
   if (e.Column.Header.Equals("Asset"))
   {
      // Create a new template column
      var templateColumn = new DataGridTemplateColumn
      {
         Header = e.PropertyName,
         // ...set other properties
      };

      // Create a data template (or get one from a resource dictionary)
      var template = new DataTemplate(typeof(Report));

      // ...populate the data template and set bindings if needed

      // Set the cell template
      templateColumn.CellTemplate = template;

      // Do the same as above for the editing template if needed
      templateColumn.CellEditingTemplate = template;

      // Overwrite the auto-generated column
      e.Column = templateColumn;
   }

   // ...handle other columns or leave them as they are
}

【讨论】:

    猜你喜欢
    • 2014-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-09
    相关资源
    最近更新 更多