简体   繁体   English

WPF Datagrid绑定错误,列标题中带有点

[英]WPF Datagrid binding errors with dots in column headers

I have a .Net datatable that I am using as a source to a WPF datagrid. 我有一个.Net数据表,用作WPF数据网格的源。 The problem I have is that some of the column headers in the datatable contain dots. 我的问题是数据表中的某些列标题包含点。 When binding the datatable to the datagrid, the columns containing dots are displayed, but contain no data. 将数据表绑定到数据网格时,将显示包含点的列,但不包含数据。

After reading around on the net I have worked out that the dots are a special notation used within the databinding engine and are confusing the datagrid's binding to the table. 在网上阅读后,我发现点是数据绑定引擎中使用的特殊符号,并且混淆了数据网格到表的绑定。

I have tried manually creating the datagrid columns + bindings and adding square brackets to negate the dots. 我尝试手动创建datagrid列+绑定,并添加方括号以使点无效。 This works fine but then breaks when I sort a column. 这工作正常,但是当我对列进行排序时会中断。 This article mentions hooking into the sorting event to remove the [] on the sorting event. 本文提到挂钩到排序事件以删除排序事件上的[]。 There wasnt much detail of how to achieve this and what I did try did not seem to get rid of the error. 如何实现这一目标没有太多细节,我尝试过的工作似乎也没有摆脱错误。

Please let me know if you require anymore information. 如果您需要更多信息,请告诉我。

As you've discovered, dot notation for anything other than Binding is problematic with WPF. 正如您所发现的那样,WPF除了Binding以外的其他任何点符号都存在问题。 What I'd recommend is to revise your headers to alias the column names with dot notation: 我建议您修改标题,以点名称为列名加上别名:

Col.A should be Col_A
Col.B should be Col_B
etc...

If the headers are coming from a direct SQL query, alias the sql column names in the same manner. 如果标头来自直接的SQL查询,则以相同的方式为sql列名称添加别名。

Going down the path of using the dot notation will just continue leading into one hackish fix to resolve the previous 'fix'. 沿着使用点符号的道路前进,只会继续导致一个骇人的修复程序来解决先前的“修复程序”。 All of this can be easily resolved by just revising your naming conventions. 只需修改命名约定,即可轻松解决所有这些问题。

Magnus Montin has solved the question at Microsot WPF Forum : Magnus Montin 在Microsot WPF论坛上解决了这个问题

AutoGeneratedColumns are rarely useful in real-world scenarios. AutoGeneratedColumns在实际场景中很少有用。 But you could also handle the AutoGeneratingColumn event: 但是您也可以处理AutoGeneratingColumn事件:

<DataGrid Name="dataGrid" AutoGenerateColumns="True" AutoGeneratingColumn="dataGrid_AutoGeneratingColumn" />


 private void dataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
 {
    e.Column = new DataGridTextColumn() { Header = e.PropertyName, Binding = new Binding("[" + e.PropertyName + "]") };
 }

Anyway, this kind of view related code certainly belongs to the view. 无论如何,这种与视图相关的代码当然属于视图。 The view model doesn't know nor care about the fact that the DataGrid control cannot display the actual data for some reason. 视图模型既不知道也不关心DataGrid控件由于某种原因而无法显示实际数据的事实。 This has to be and should be fixed in the view. 该视图必须并且应该在视图中修复。

It works like a charm! 它就像一个魅力! My example started to work: 我的示例开始起作用:

XAML: XAML:

<DataGrid ColumnWidth="35" ItemsSource="{Binding EmployeeDataTable, 
    IsAsync=True}" VirtualizingStackPanel.IsVirtualizing="true" 
    EnableRowVirtualization="True" EnableColumnVirtualization="True"
    MaxWidth="2560" MaxHeight="1600"  
    VirtualizingStackPanel.VirtualizationMode="Recycling" 
    VirtualizingPanel.IsVirtualizingWhenGrouping="True"/>  

Code behind: 后面的代码:

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
   e.Column = new DataGridTextColumn() { 
       Header = e.PropertyName, 
       SortMemberPath = e.PropertyName, //To allow for sorting on a column 
       Binding = new Binding("[" + e.PropertyName + "]") 
   };
}

ViewModel : ViewModel

private DataTable employeeDataTable;

public DataTable EmployeeDataTable
{
   get { return employeeDataTable; }
   set
   {
      employeeDataTable = value;
      OnPropertyChanged("EmployeeDataTable");
   }
}

private void PopulateDataTable()
{
    var _ds = new DataSet("Test");
    employeeDataTable = new DataTable();
    employeeDataTable = _ds.Tables.Add("DT");
    for (int i = 0; i < 800; i++)
    {
       if(i%2==0)
           employeeDataTable.Columns.Add(i.ToString() + ".");
       else
           employeeDataTable.Columns.Add(i.ToString() + "/");
    }
    for (int i = 0; i < 2; i++)
    {
       var theRow = employeeDataTable.NewRow();
       for (int j = 0; j < 800; j++)
       {
          if (j % 2 == 0)
          {
            //theRow[j] = j.ToString();
            theRow[j] = "a";
          }
          else
            theRow[j] = CreateDoubleValue(j).ToString();
     }
    employeeDataTable.Rows.Add(theRow);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM