2012-06-02 166 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

相關問題