c# - 如何構建具有未知列數的WPF數據網格




xaml datagrid (2)

.Net中有 DataTable 。 它的主要目的是與關係數據庫進行通信,但它可以很好地用於存儲,顯示和編輯表格數據(例如,讀取和顯示.csv / Excel文件 - > Wpf中的 DataTable + DataGridView ,WinForms中的 DataTable + DataGridView )。

DataTable列(DataColumn)可以在運行時添加/刪除,DataGrid為它們自動生成列(DataGridColumn)(默認情況下啟用),使用標題的Name屬性。 DataTable也支持開箱即用的排序和過濾。

注意:分配新的ItemsSource時,DataGrid不會清除 Columns 。 因此可以有一些預定義的列並使用自動生成。

注意:DataGrid默認創建 DataGridTextColumn 。 如果需要更複雜的模板,可以通過 AutoGeneratingColumn 事件攔截該過程( 參見示例

這是一個例子:

public class MyViewModel
{
    public DataTable Test { get; set; }
}

public MyWindow()
{
    InitializeComponent();
    var vm = new MyViewModel
                {
                    Test = new DataTable
                        {
                            Columns = {"A", "B", "C"}
                        }
                };            
    this.DataContext = vm;

}

XAML

<DataGrid AutoGenerateColumns="True"
          ItemsSource="{Binding Path=Test.DefaultView}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="#"/>
    </DataGrid.Columns>
</DataGrid>

結果(我輸入了一些值)

我需要從我從txt獲得的字符串數組的集合中構建和顯示WPF數據網格。 問題是我不知道先驗的是列數,即單個數組中的項數。 所以我在我的xaml中定義了 <DataGrid Grid.Row="2" ItemsSource="{Binding Path=Rows}" />

我試圖在我的視圖模型中填充它,但我不能簡單地將我的數組的集合(Observable Collection)作為項目源,因為datagrid將只顯示空行。

我也可以使用其他方法而不是Observable集合,因為我使用相同的方法生成我的數組

這是我的Observable Collection:

ObservableCollection<string[]> Rows = new ObservableCollection<string[]>;

在這個方法中我填寫了集合

foreach(ListViewItem item in wsettings.lista)
        {                 
            TextBlock line = item.Content as TextBlock;
            string txt = line.Text;
            string[] x = txt.Split(stringSeparators, StringSplitOptions.None);               
            Rows.Add(x);
        }    

請不要介意分手前的第一部分。 我從我之前使用的文本塊的列表視圖中獲取數據(我有我的理由)。

EDIT1:使代碼更具可讀性

EDIT2:標題必須是用戶必須設置的組合框


如果在編譯時不知道列數,則需要以編程方式創建列。 這在視圖中應該非常簡單。 以下示例代碼應該為您提供以下建議:

public MainWindow()
{
    InitializeComponent();
    var viewModel = new ViewModel();
    var rows = viewModel.Rows;
    int numberOfColumns = rows[0].Length; //assume all string[] have the same length
    DataContext = new VM1();

    for (int i = 0; i < numberOfColumns; ++i)
    {
        dataGrid1.Columns.Add(new DataGridTextColumn() { Binding = new Binding("[" + i + "]"), Header = i.ToString() });
    }
    dataGrid1.ItemsSource = rows;
}




datagrid