c# - Cómo construir una cuadrícula de datos WPF con un número desconocido de columnas
xaml datagrid (2)
Hay una
clase
DataTable
en .Net.
Su propósito principal es comunicarse con la base de datos relacional, pero se puede usar muy bien para almacenar, mostrar y editar datos tabulares (por ejemplo, leer y mostrar archivos .csv / Excel ->
DataTable + DataGrid
en wpf,
DataTable + DataGridView
en WinForms).
Las columnas DataTable (DataColumn) se pueden agregar / eliminar en tiempo de ejecución y DataGrid genera automáticamente columnas (DataGridColumn) para ellas (habilitada de forma predeterminada), utilizando la propiedad Name para los encabezados. También DataTable admite la clasificación y el filtrado listos para usar.
nota: DataGrid no borra
Columns
cuando se asigna una nueva ItemsSource.
Por lo tanto, es posible tener algunas columnas predefinidas y usar también autogenerar.
nota: DataGrid crea
DataGridTextColumn
s de forma predeterminada.
Si se requiere una plantilla más compleja, el proceso se puede interceptar mediante el evento
AutoGeneratingColumn
(
ver ejemplo
)
Aquí hay un ejemplo:
código
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>
el resultado (ingresé algunos valores)
Necesito construir y mostrar una cuadrícula de datos WPF de una colección de matriz de cadenas que obtuve de un txt.
El problema es que no sé a priori cuál será el número de columnas, es decir, el número de elementos en la matriz única.
Así que
<DataGrid Grid.Row="2" ItemsSource="{Binding Path=Rows}" />
en mi xaml
<DataGrid Grid.Row="2" ItemsSource="{Binding Path=Rows}" />
Intenté completarlo en mi Modelo de vista, pero no puedo simplemente colocar mi colección (Colección observable) de matriz como fuente de elemento, ya que la cuadrícula de datos mostrará solo filas en blanco.
También puedo usar otro enfoque sobre la colección Observable ya que produzco mi matriz con el mismo método
Esta es mi colección observable:
ObservableCollection<string[]> Rows = new ObservableCollection<string[]>;
en este método lleno la colección
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);
}
Por favor, no importa la primera parte antes de la división. Tomo mis datos de una vista de lista del bloque de texto que usé antes (tengo mi razón).
EDITAR1: hizo el código más legible
EDIT2: el encabezado debe ser un cuadro combinado que un usuario debe establecer
Si no conoce el número de columnas en tiempo de compilación, debe crear las columnas mediante programación. Esto debería ser bastante sencillo de hacer en la vista. El siguiente código de muestra debería darle la idea:
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;
}