从ObservableCollection简单数据绑定到DataGrid(WPF)?

时间:2011-10-17 16:03:32

标签: wpf data-binding c#-4.0 mvvm .net-4.0

我有一个'ObservableCollection'存储需要粘贴到DataGrid中的格式化ColumnLabel。

该集合可以有许多不同的条目,大小为'N',因此我的DataGrid中会有'N'个列。定义如下:

    private ObservableCollection<string> _stockColumnLabels;
    public ObservableCollection<string> StockColumnLabels 
    {
        get 
        {
            if (_stockColumnLabels == null)
            {
                _stockColumnLabels = new ObservableCollection<string>();
                return _stockColumnLabels;
            }
            return _stockColumnLabels; 
        }
        set
        {
            _stockColumnLabels = value;
            //OnPropertyChanged("StockColumnLabels");
        } 
    }

此集合将包含的示例数据:

  1. “1”
  2. “2”
  3. “3”
  4. “4”
  5. “5”
  6. N.B, 当然,所有字符串都可以看作是在GUI上查看时表示列的单行数据。

    为了DataBinding,集合被包装到一个属性中,并且存在于ViewModel中,而DataGrid存在于View中。运行App.cs文件时,View的DataContext设置为RunTime!

    public partial class App : Application
    {
        protected override void OnStartup(StartupEventArgs e)
        {
            base.OnStartup(e);
    
            MainWindow window = new MainWindow();
            window.DataContext = new FSEnquiryViewModel();
            window.Show();
        }
    }
    

    GUI(VIEW)

    目前由于在此项目中设置的要求的性质,列名必须格式化为ProductCode,以便使生活更轻松,我创建了一个DataGrid,它只包含一行数据,这些数据是列名然后在下面的另一个DataGrid将保存行值。不要担心第二个DataGrid,我将在稍后对其进行排序,因为设置完全相同。现在,有人可以帮我“将我的ViewModel中找到的ObservableCollection”绑定到我的DataGrid,它只是一个数据条。

    看起来像

               1         2         ...       n         <- 'DataGrid1'
    Row1 |     1    |    3    |    5    |    6    |    <- 'DataGrid2'
    Row2 |     3    |    2    |    1    |    8    |
    

3 个答案:

答案 0 :(得分:1)

我的下面的代码希望回答允许您绑定来自未知数量源的数据的问题,每个结果的大小以及可能使用的列的潜在数量可能是未知的。然后将结果逐行缓慢地形成一个动态集合,代表最终的数据布局。

基本上或多或少与BlindMeis的答案相同,但是他发布的语法在语法上是不正确的,并且在发布之前看起来并没有经过测试。我下面的代码是我目前正在使用的代码。

下面你会发现,对于我来说,假设你有一个或多个结果集,那对我有用。

  1. 声明一个表格以保存结果。

    DataTable shapedResultsTable = new DataTable();

  2. 接下来,将过滤DB调用或程序中的一些结果,这些结果是您尝试重新塑造的结果。类似的东西:

        foreach (DataRow row in whFreeResults.Rows)
        {
            // filter your results and strip exactly the data you need to represent your column names.
            // dump your results into a sample list e.g: 'columnNamesFormatted'
    
        }
    
  3. 获得列名列表后,将它们添加到上面声明的数据表中。

        foreach (string column in columnNamesFormatted)
        {
            shapedResultsTable.Columns.Add(column, typeof(string));
        }
    
  4. 接下来,声明,实例化并填充未知大小的列表,因为结果的大小为n或金额n,以存储行值。

  5. 接下来,对于要在新的“整形结果数据表”中显示的每一行数据重复步骤2和3,对于结果集中找到的每一行,重复多一行。

  6. 一旦有几个集合代表您要添加到数据表的每一行。按照您希望它们显示的顺序添加它们。

    shapedResultsTable.Rows.Add(totalsArray.ToArray()); shapedResultsTable.Rows.Add(branchRowValues.ToArray());

  7. 最后,将您的DataTable分配给'DataBinded Property'。

    StockResultsTable = shapedResultsTable;

  8. 绑定的属性可能如下所示:

    private DataTable _stockResultsTable;
    public DataTable StockResultsTable
    {
        get { return _stockResultsTable; }
        set 
        { 
            _stockResultsTable = value;
            OnPropertyChanged("StockResultsTable"); // <--- defo' need this one.
        }
    }
    
  9. 最后,前端的xaml看起来像:

            <DataGrid Height="179" 
              HorizontalAlignment="Left" 
              Margin="151,0,0,211" 
              Name="dgStockInfo" 
              VerticalAlignment="Bottom" 
              Width="393" 
              ItemsSource="{Binding Path = StockResultsTable}" AutoGenerateColumns="True" Padding="0,10" FontSize="14" />
    
  10. 我不知道为什么自动生成列属性已启用,但这对我有用。

    步骤1-9对我有用,处理从查询或SProc返回的结果的示例数据集,上面的步骤简要概述了我在显示我必须运行的众多查询的结果时所做的工作来自许多不同SProcs的数据,但有一个共同的基础主题,允许它们以常见的列名显示。

    请注意,在添加一行数据的情况下会遇到麻烦,其中DataTable包含更多成员。一个有6列的DT,但是你要添加一个来自不同查询的行,它有7个单独的数据单元格。这不起作用,只需添加一个尚未存在的新列,然后重试。

答案 1 :(得分:0)

您的列标题集合是否与“数据”集合的大小相同?如果是这样,您可以在InializeComponent()之后执行此操作。 (注意:它可能会破坏一些MVVM规则,但这取决于你想要的严格程度)

        InitializeComponent();
        DataContext = vm;
        dataGrid1.ItemsSource = vm.DgData; // this can also be done via XML binding
        dataGrid1.AutoGenerateColumns = true;
        foreach (var column in dataGrid1.Columns)
        {
            column.Header = vm.ColumnHeaders[column.DisplayIndex];
        }     

答案 2 :(得分:-2)

编辑:DataTable完美运行。 只需使用ViewTable为视图构建您的集合即可。我假设您的标题集与数据大小相同。

this.dt = new DataTable();

dt.Columns.Add(new Column("1")); //1..n columns
dt.Columns.Add(new Column("n"));

然后为您以前定义的列和您拥有的数据行输入数据

var newrow = dt.NewRow();
newrow[0] = "value1"; //0..n-1 columns
dt.AddRow(newrow);

viewmodel属性

publlic DataTable MyDynamicDataTable {get{return this.dt;}}
xaml中的

绑定

 <DataGrid ItemsSource="{Binding MyDynamicDataTable}" AutogenerateColumns="true" />

您无需在视图数据网格中执行任何操作,所有信息都来自viewmodel。