2012-06-02 116 views
3

我有一个包含Curve对象列表的Log对象。每条曲线都有一个Name属性和一个双精度数组。我希望名称位于列标题和它下面的数据中。我有一个用datagid的用户控件。这是XAML;如何将数组绑定到WPF数据网格中的列

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

我甚至不会显示我试图用绑定的数组“数据”的代码,因为没有甚至差点。我确信我错过了一些简单的事情,但经过几个小时的搜索网络,我不得不乞求答案。

+0

可能重复的[如何显示的数组元素在WPF DataGrid中?](http://stackoverflow.com/questions/5582226/how-can-i-display-array-elements-in-a-wpf-datagrid) –

+0

@dbaseman:这对阵列没有帮助因为没有b处理它们的内在逻辑。 –

+0

@ H.B。谢谢澄清。我误解了这个问题。 – McGarnagle

回答

3

您需要将日志数据转换为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; 
+0

谢谢你的例子。它完美的作品。不幸的是有两个问题。数据网格太慢了。需要10秒才能打开25,000个条目。像这样的小数字应该几乎立即打开。此外,我需要能够删除日志中的单个曲线,并看到网格中的某个列消失。 – spainchaud

+0

为了进一步解释,我想模拟一个现有的程序(Windows窗体),它使用类似于我所拥有的数据结构。该程序可以非常快地打开更大的数据集。我认为它可能使用第三方数据网格控件。我将不得不问作者他是如何做到的。 – spainchaud

+0

我已经测试了10条250,000条曲线。这个关键点需要500毫秒(可能会有所改进)。网格显示瞬间。应对事件(CurveRemoved)应该很简单,然后删除列和所有关联的值。 – Phil

相关问题