如何使用列数可变的 C# WPF ListView
How to use C# WPF ListView with variable number of columns
我想从外部各种来源(如文本文件、csv 文件、用户输入等)加载一些数据,并使用 C# WPF 在列表视图中显示。我一次只需要显示一个源,并且列数在一个源内是固定的,但不同的源可能包含不同的列数,例如
File1 可能有以下列:名称、编号、Cat1、Cat2、Cat3
File2 可能有以下列:名称、编号、CatA、CatB
File3 可能有以下列:名称、索引、Type1、...、TypeN
...
好像C#WPF中的listview只能使用已知列数,是否可以像上面的数据一样,在RUNTIME中使用只知道列数的listview?或者我应该使用不同的方法,我还不知道。谢谢。
将 csv 转换为 table(仅举个例子,有些库可以更好地完成这项工作):
public static class ExtensionMethods
{
public static DataTable ConvertToDataTable(this string input)
{
DataTable result = new DataTable();
using (StringReader reader = new StringReader(input))
{
string[] columnNames = reader.ReadLine().Split(';'); //or other character
foreach (var columnName in columnNames)
{
result.Columns.Add(columnName, typeof(string));
}
while (reader.Peek() > 0)
{
result.Rows.Add(reader.ReadLine().Split(';'));
}
}
return result;
}
}
UI示例:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Name="btnLoad" Content="Load" Click="BtnLoad_OnClick"/>
<DataGrid Name="dgData" Grid.Row="1" ItemsSource="{Binding}"/>
</Grid>
</Window>
以及后面的正确代码:
public partial class MainWindow : Window
{
private DataTable table;
public MainWindow()
{
InitializeComponent();
}
private void BtnLoad_OnClick(object senderIn, RoutedEventArgs eIn)
{
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == true)
{
string content = File.ReadAllText(dialog.FileName);
table = content.ConvertToDataTable();
dgData.DataContext = table;
}
}
}
测试数据:
Name;Number;Cat1;Cat2;Cat3
someName;someNumber;someCat1;someCat2;someCat3
someOtherName;someOtherNumber;someOtherCat1;someOtherCat2;someOtherCat3
看起来像:
我想从外部各种来源(如文本文件、csv 文件、用户输入等)加载一些数据,并使用 C# WPF 在列表视图中显示。我一次只需要显示一个源,并且列数在一个源内是固定的,但不同的源可能包含不同的列数,例如
File1 可能有以下列:名称、编号、Cat1、Cat2、Cat3
File2 可能有以下列:名称、编号、CatA、CatB
File3 可能有以下列:名称、索引、Type1、...、TypeN
...
好像C#WPF中的listview只能使用已知列数,是否可以像上面的数据一样,在RUNTIME中使用只知道列数的listview?或者我应该使用不同的方法,我还不知道。谢谢。
将 csv 转换为 table(仅举个例子,有些库可以更好地完成这项工作):
public static class ExtensionMethods
{
public static DataTable ConvertToDataTable(this string input)
{
DataTable result = new DataTable();
using (StringReader reader = new StringReader(input))
{
string[] columnNames = reader.ReadLine().Split(';'); //or other character
foreach (var columnName in columnNames)
{
result.Columns.Add(columnName, typeof(string));
}
while (reader.Peek() > 0)
{
result.Rows.Add(reader.ReadLine().Split(';'));
}
}
return result;
}
}
UI示例:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Button Name="btnLoad" Content="Load" Click="BtnLoad_OnClick"/>
<DataGrid Name="dgData" Grid.Row="1" ItemsSource="{Binding}"/>
</Grid>
</Window>
以及后面的正确代码:
public partial class MainWindow : Window
{
private DataTable table;
public MainWindow()
{
InitializeComponent();
}
private void BtnLoad_OnClick(object senderIn, RoutedEventArgs eIn)
{
OpenFileDialog dialog = new OpenFileDialog();
if (dialog.ShowDialog() == true)
{
string content = File.ReadAllText(dialog.FileName);
table = content.ConvertToDataTable();
dgData.DataContext = table;
}
}
}
测试数据:
Name;Number;Cat1;Cat2;Cat3
someName;someNumber;someCat1;someCat2;someCat3
someOtherName;someOtherNumber;someOtherCat1;someOtherCat2;someOtherCat3
看起来像: