【问题标题】:How to build A WPF Datagrid with an unknown number of columns如何构建具有未知列数的 WPF 数据网格
【发布时间】:2017-10-27 09:57:50
【问题描述】:

我需要从我从 txt 获得的字符串数组集合中构建和显示 WPF 数据网格。问题是我不知道先验将是列数,即单个数组中的项目数。所以我在我的 xaml 中定义了<DataGrid Grid.Row="2" ItemsSource="{Binding Path=Rows}" />

我试图将它填充到我的视图模型中,但我不能简单地将我的数组集合(可观察集合)作为项目源,因为数据网格将只显示空白行。

我还可以在 Observable 集合上使用其他方法,因为我使用相同的方法生成数组

这是我的 Observable 集合:

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:标题必须是用户必须设置的组合框

【问题讨论】:

  • 你不应该用 TextBlocks 做这些奇怪的事情。您应该将 ItemsSource 绑定到视图模型中的 ObservableCollection,就像您尝试做的那样。如果您向我们展示您尝试这样做时的所有代码,我们可以帮助您正确处理。
  • 你期望什么列标题?
  • @Daniele,您可以使用DataTable 来存储值并将其显示在DataGrid 中
  • @ASh 你能解释一下吗?我创建了一个 DataTable,并填充了我的数据。我修改了我的 xamul 如下: 但我的数据网格仍然是空的。测试是我的数据表。我什至尝试将我的数据表保存为 DataView 但没有结果
  • @DanieleSartori, AutoGenerateColumns 应该是 TrueItemsSource 需要 IEnumerable (dataTable.DefaultView, ItemsSource="{Binding Path=DefaultView}" )。

标签: c# wpf xaml datagrid


【解决方案1】:

.Net 中有DataTable class。它的主要目的是与关系数据库通信,但它可以很好地用于存储、显示和编辑表格数据(例如读取和显示 .csv/Excel 文件 -> wpf 中的DataTable + DataGrid,WinForms 中的DataTable + DataGridView)。

DataTable 列 (DataColumn) 可以在运行时添加/删除,DataGrid 使用标题的 Name 属性为它们自动生成列 (DataGridColumn)(默认启用)。 DataTable 还支持开箱即用的排序和过滤。

注意:分配新的 ItemsSource 时,DataGrid 不会清除 Columns。所以可以有一些预定义的列并使用自动生成。

注意:DataGrid 默认创建DataGridTextColumns。如果需要更复杂的模板,可以通过AutoGeneratingColumn事件(see example)拦截进程

这是一个例子:

代码

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>

结果(我输入了一些值)

【讨论】:

    【解决方案2】:

    如果您在编译时不知道列数,则需要以编程方式创建列。这在视图中应该非常简单。下面的示例代码应该会给你这个想法:

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

    【讨论】:

    • 这肯定是一个解决方案。我只是想在 View Model 中这样做
    • 视图模型不应该负责创建 DataGrid 列。这将打破 MVVM 模式。这是属于视图的基于视图的功能。 VM 只是公开一个集合供视图绑定。
    • @mm8 你如何将集合与绑定联系起来?
    猜你喜欢
    • 2019-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多