且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

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

更新时间:2022-12-27 15:15:30

Magnus Montin 已经解决了问题在Microsot WPF 论坛:

AutoGeneratedColumns 在实际场景中很少有用.但您还可以处理 AutoGeneratingColumn 事件:

私有无效 dataGrid_AutoGeneratingColumn(对象发送者,DataGridAutoGeneratingColumnEventArgs e){e.Column = new DataGridTextColumn() { Header = e.PropertyName, Binding = new Binding("[" + e.PropertyName + "]") };}

反正这种视图相关的代码肯定是属于视图的.视图模型不知道也不关心 DataGrid由于某种原因,控件无法显示实际数据.这必须是并且应该在视图中修复.

它就像一个魅力!我的例子开始起作用了:

XAML:

背后的代码:

private void DataGrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e){e.Column = new DataGridTextColumn() {Header = e.PropertyName,SortMemberPath = e.PropertyName,//允许对列进行排序Binding = new Binding("[" + e.PropertyName + "]")};}

视图模型:

私有数据表employeeDataTable;公共数据表员工数据表{得到 { 返回员工数据表;}放{员工数据表 = 值;OnPropertyChanged("EmployeeDataTable");}}私有无效 PopulateDataTable(){var _ds = new DataSet("测试");员工数据表 = 新数据表();员工数据表 = _ds.Tables.Add("DT");for (int i = 0; i 

I have a .Net datatable that I am using as a source to a WPF datagrid. 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. 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.

Magnus Montin has solved the question at Microsot WPF Forum :

AutoGeneratedColumns are rarely useful in real-world scenarios. But you could also handle the AutoGeneratingColumn event:

<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. This has to be and should be fixed in the view.

It works like a charm! My example started to work:

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:

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);
    }
}