【问题标题】:How do I bind arrays to columns in a WPF datagrid如何将数组绑定到 WPF 数据网格中的列
【发布时间】:2012-06-02 22:36:01
【问题描述】:

我有一个包含 Curve 对象列表的 Log 对象。每条曲线都有一个 Name 属性和一个双精度数组。我希望名称位于列标题及其下方的数据中。我有一个带有 datagid 的用户控件。这是 XAML;

<UserControl x:Class="WellLab.UI.LogViewer"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="500" d:DesignWidth="500">
<Grid>
    <StackPanel Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="stackPanel1" VerticalAlignment="Stretch" Width="Auto">
        <ToolBarTray Height="26" Name="toolBarTray1" Width="Auto" />
        <ScrollViewer Height="Auto" Name="scrollViewer1" Width="Auto" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Visible" CanContentScroll="True" Background="#E6ABA4A4">
            <DataGrid AutoGenerateColumns="True" Height="Auto" Name="logDataGrid" Width="Auto" ItemsSource="{Binding}" HorizontalAlignment="Left">
            </DataGrid>
        </ScrollViewer>
    </StackPanel>
</Grid>

在后面的代码中我已经弄清楚了如何创建列并命名它们,但我还没有弄清楚如何绑定数据。

public partial class LogViewer
{
    public LogViewer(Log log)
    {
        InitializeComponent();

        foreach (var curve in log.Curves)
        {
            var data = curve.GetData();
            var col = new DataGridTextColumn { Header = curve.Name };
            logDataGrid.Columns.Add(col);
        }
    }
}

我什至不会显示我试图用来绑定数组“数据”的代码,因为没有任何东西可以接近。我确信我错过了一些简单的东西,但是在网上搜索了几个小时之后,我不得不来乞求答案。

【问题讨论】:

  • @dbaseman:这对数组没有帮助,因为没有内置逻辑来处理它们。
  • @H.B.感谢您的澄清。我误解了这个问题。
  • 通常,当您将数组绑定到 DataGrid 时,数组的每个成员都是一行,而不是一列。在您的情况下,您可以有两列,一列用于名称,另一列用于数据。如果 data 本身是一个数组,那么您可以创建一个模板列以使用某种 ItemsControl 绑定到每个 Data 数组。
  • Moozhe 说得对,数组的每个成员都是一行。这就是我一直结束的,这对我不起作用。我希望最终的解决方案有两个数据网格。一个用于标题,即与曲线关联的名称,以及一个单独的数据网格,在滚动查看器中,用于保存曲线数据。曲线数据是一个双精度数组,通常包含数千个元素。

标签: wpf arrays binding datagrid


【解决方案1】:

您需要将日志数据转换为RowDataItem 的集合,其中每一行包含一个双精度值集合,每个Curve 一个值。同时可以提取列名。所以数据最终会是这样。

public class PivotedLogData : ViewModelBase
{
    public PivotedLogData(Log log)
    {
        ColumnNames = log.Curves.Select(c => c.Name).ToList();

        int numRows = log.Curves.Max(c => c.Values.Count);

        var items = new List<RowDataItem>(numRows);

        for (int i = 0; i < numRows; i++)
        {
            items.Add(new RowDataItem(
                          log.Curves.Select(
                              curve => curve.Values.Count > i
                                           ? curve.Values[i]
                                           : (double?) null).ToList()));
        }

        Items = items;
    }

    public IList<string> ColumnNames { get; private set; }
    public IEnumerable<RowDataItem> Items { get; private set; }
}

public class RowDataItem
{
    public RowDataItem(IList<double?> values)
    {
        Values = values;
    }

    public IList<double?> Values { get; private set; }
}

然后你会像上面一样创建DataGridTextColumn 项目,但要使用合适的绑定

var pivoted = new PivotedLogData(log);

int columnIndex = 0;

foreach (var name in pivoted .ColumnName)
{
    dataGrid.Columns.Add(
        new DataGridTextColumn
            {
                Header = name,
                Binding = new Binding(string.Format("Values[{0}]", columnIndex++))
            });
}

现在将数据绑定到网格

dataGrid.ItemsSource = pivoted.Items;

【讨论】:

  • 谢谢你的例子。它完美地工作。不幸的是有两个问题。数据网格太慢了。打开一个包含 25,000 个条目的网格需要 10 秒。像这样的一小部分应该几乎立即打开。此外,我需要能够删除日志中的一条曲线并看到我的网格中的一列消失。
  • 为了进一步解释,我试图模拟一个现有程序(Windows 窗体),它使用与我所拥有的数据结构相似的数据结构。该程序非常快速地打开更大的数据集。我认为它可能正在使用第三方数据网格控件。我得问问作者他是怎么做到的。
  • 我用 250,000 个条目的 10 条曲线进行了测试。枢轴花了 500 毫秒(也许可以改进)。网格立即显示。响应一个事件(CurveRemoved)然后删除一列和所有相关值应该很简单。
  • 我能够通过将数据网格放入 DockPanel 而不是 StackPanel 来显着加快数据网格的速度,StackPanel 也给了我滚动条。我计时了 4 个案例,其中包括旋转和填充数据网格。这是我的时代:Open log MPR Modeled。因此,较小的情况约为 2.5 秒。也许我可以找到另一个加速。所用时间:00:00:04.69 点数:42500 打开日志 DTKRes 建模所用时间:00:00:02.92 点数:22500 打开日志 RADRAngleMM 所用时间:00:00:02.51 点数:22500 打开日志 RADRTargMM 时间采取 : 00:00:02.32 点数: 22500
  • 我会在几分钟后去上班,我可以看看他们是如何填写他们的 winforms 控件的。
猜你喜欢
  • 2011-05-28
  • 1970-01-01
  • 2011-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
相关资源
最近更新 更多