displaying a "dynamic" table

I'd like to display a table of items in WPF. In general that's not that hard, except that:

  • I know, which columns I want to display only at runtime (user in a way defines them), and
  • I'd like to avoid using codebehind: the XAML, where I want to display the table is inside a DataTemplate , which is inside another DataTemplate etc. Introducing CodeBehind there will be problematic (though I will do that if I have no other options).
  • I though of using WPF's DataGrid , which is smart enough to extract column names in runtime (depending on properties of collection items), but I know which columns I want to display only at runtime - I would have to create object with specific properties at runtime, what is also problematic (if possible).

    Also, I don't really need to use specifically the DataGrid , as this will be simple table of strings for preview only - it may be as well displayed, say, inside Grid with ItemsControl - I just need to provide a view with columns and rows.

    So the questions are:

  • How to customize displayed columns in DataGrid only from ViewModel (DataContext) and XAML?, or
  • How to display tabular for preview data when columns are known at runtime only?

  • Since it seems like there is interest for this problem and I found solution myself, here it goes (attached properties rulez!)

    For clarity, I created model classes to wrap list of list of strings:

    public class TableDataRow
    {
        public TableDataRow(List<string> cells)
        {
            Cells = cells;
        }
    
        public List<string> Cells { get; }
    }
    
    public class TableData
    {
        public TableData(List<string> columnHeaders, List<TableDataRow> rows)
        {
            for (int i = 0; i < rows.Count; i++)
                if (rows[i].Cells.Count != columnHeaders.Count)
                    throw new ArgumentException(nameof(rows));
    
            ColumnHeaders = columnHeaders;
            Rows = rows;
        }
    
        public List<string> ColumnHeaders { get; }
        public List<TableDataRow> Rows { get; }
    }
    

    Now we define the attached property:

    public static class DataGridHelper
    {
        private static void TableDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var dataGrid = d as DataGrid;
            var tableData = e.NewValue as TableData;
            if (dataGrid != null && tableData != null)
            {
                dataGrid.Columns.Clear();
                for (int i = 0; i < tableData.ColumnHeaders.Count; i++)
                {
                    DataGridColumn column = new DataGridTextColumn
                    {
                        Binding = new Binding($"Cells[{i}]"),
                        Header = tableData.ColumnHeaders[i]
                    };
                    dataGrid.Columns.Add(column);
                }
    
                dataGrid.ItemsSource = tableData.Rows;
            }
        }
    
        public static TableData GetTableData(DependencyObject obj)
        {
            return (TableData)obj.GetValue(TableDataProperty);
        }
    
        public static void SetTableData(DependencyObject obj, TableData value)
        {
            obj.SetValue(TableDataProperty, value);
        }
    
        // Using a DependencyProperty as the backing store for TableData.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TableDataProperty =
            DependencyProperty.RegisterAttached("TableData", 
                typeof(TableData), 
                typeof(DataGridHelper), 
                new PropertyMetadata(null, TableDataChanged));
    }
    

    The usage is trivial:

    (...)
    xmlns:h="clr-namespace:<namespace-of-DataGridHelper>"
    (...)    
    
    <DataGrid AutoGenerateColumns="False" h:DataGridHelper.TableData="{Binding ResultData}" />
    

    Obviously DataContext must publish TableData via ResultData . Don't forget about AutoGenerateColumns , otherwise you'll receive additional column "Cells".

    链接地址: http://www.djcxy.com/p/64740.html

    上一篇: 从大型XML文件中删除节点

    下一篇: 显示一个“动态”表格