当我在 wpf 应用程序中绑定数据表时,我得到空数据网格
I am getting null data grid, when i bind with datatable in wpf application
当我在 wpf 中使用 linq lambda 表达式绑定数据网格时,它会填充数据网格,但是当我尝试将此 linq 结果转换为数据表时,它会在我尝试过的代码下方填充空数据网格....
var join = dm.Export_Matrilas_s
.Where(rh => rh.Material_type == 5)
.Join(dm.Parti_Infos, p => p.Parti_Id, w => w.Parti_Id, (p, w) => new { p.Export_Matrilas_id, p.Material_type, p.Owncom, w.Organization, p.Date })
.Join(dm.Own_Company_Infos, r => r.Owncom, y => y.Company_Id, (r, y) => new { r, y.Organization_Name })
.Join(dm.Material_Types, n => n.r.Material_type, b => b.Id, (n, t) => new { n.r.Export_Matrilas_id, t.Meterial_Name, n.Organization_Name, n.r.Organization, n.r.Date })
.ToList();
DataTable gettbl = ToDataTable(join);
mygride.DataContext = gettbl.DefaultView;
这里我用方法
转成datatable
public DataTable ToDataTable<T>(IList<T> data)// T is any generic type
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
// table.Columns.Add(prop.DisplayName,prop.PropertyType);
table.Columns.Add(prop.DisplayName, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
object[] values = new object[props.Count];
DataRow row;
foreach (var record in data)
{
row = table.NewRow();
for (int i = 0; i < table.Columns.Count; i++)
{
values[i] = props[i].GetValue(record) != null ? props[i].GetValue(record) : DBNull.Value;
}
table.Rows.Add(row);
}
table.Rows.Add(values);
return table;
}
这是我的 xaml 代码:
<UserControl x:Class="Iqbal_Silks.Export_Tanee_Records"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Height="700" Width="900">
<UserControl.Resources>
<ResourceDictionary Source="../Themes/Dictionary1.xaml"/>
</UserControl.Resources>
<Grid >
<DataGrid x:Name="mygride" Margin="3,243,10,64" AutoGenerateColumns="False" AlternatingRowBackground="AliceBlue" VerticalContentAlignment="Center" CanUserResizeRows="False" HorizontalContentAlignment="Center" ScrollViewer.PanningMode="VerticalFirst" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Export ID" Width="Auto" Binding="{Binding Export_Matrilas_id}"/>
<DataGridTextColumn Header="Materials " Width="Auto" Binding="{Binding Meterial_Name}" />
<DataGridTextColumn Header="Company" Width="Auto" Binding="{Binding Organization_Name}"/>
<DataGridTextColumn Header="Client" Width="Auto" Binding="{Binding Organization}"/>
<DataGridTextColumn Header="Date" Width="Auto" Binding="{Binding Date}"/>
</DataGrid.Columns>
</DataGrid>
<Button Content="Excel Records" x:Name="btnviewchallan_Copy" Style="{StaticResource Hdrclose}" HorizontalAlignment="Left" Margin="616,641,0,0" VerticalAlignment="Top" Width="94" Height="27" Click="BtnviewchallanCopyClick" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="10,644,768,32">
<Button Name="btnFirstPage" Content="<<" Click="btnFirstPage_Click"/>
<Button Name="btnPreviousPage" Content="<" Click="btnPreviousPage_Click"/>
<Label Name="lblPageIndex" Content="{Binding ElementName=root,
Path=PageIndex, UpdateSourceTrigger=PropertyChanged}" Width="Auto"/>
<Label Content="of"/>
<Label Name="lblPageNumber" Content="{Binding ElementName=root,
Path=NumberOfPages, UpdateSourceTrigger=PropertyChanged}" Width="Auto"/>
<Button Name="btnNextPage" Content=">" Click="btnNextPage_Click"/>
<Button Name="btnLastPage" Content=">>" Click="btnLastPage_Click"/>
</StackPanel>
</Grid>
绑定a有两种方法DataGrid
:
可以像您尝试的那样通过 DataContext
属性 来完成:
dataGrid1.DataContext = gettbl.DefaultView;
这里不正确,因为你的 DataContext
在这种情况下是 DataTable
本身 (gettbl) 所以这是正确的:
dataGrid1.DataContext = gettbl;
如果您使用 DataContext
,您还需要将 XAML
中的 ItemsSource
设置为:
<DataGrid ItemsSource="{Binding Path=DefaultView}">
或者另一种方法是直接使用ItemsSource
属性(那么你不需要在XAML
中添加任何额外的代码)
dataGrid1.ItemsSource = gettbl.DefaultView;
此外,我认为您的 ToDataTable
方法有一个错误。
您只向 DataTable
添加了空行,并且它比源集合多了一行。
DataRow row;
foreach (var record in data)
{
row = table.NewRow();
for (int i = 0; i < table.Columns.Count; i++)
{
values[i] = props[i].GetValue(record) != null ? props[i].GetValue(record) : DBNull.Value;
}
// You do not set the row columns anywhere.
table.Rows.Add(row);
// This would work but I'm not sure what you are trying to do.
// table.Rows.Add(values);
}
// You add an extra row here: is this intended?
table.Rows.Add(values);
我也不确定基于指定的对象属性构建数据 table 列是否是个好主意,因为您已经为数据网格定义了列,如果 T
与已定义的列具有不同的属性,那么它们将不匹配,您将看不到任何内容。
也许您已经这样做了,但如果没有考虑使用指定列名的界面或让您的数据网格自动生成列。
当我在 wpf 中使用 linq lambda 表达式绑定数据网格时,它会填充数据网格,但是当我尝试将此 linq 结果转换为数据表时,它会在我尝试过的代码下方填充空数据网格....
var join = dm.Export_Matrilas_s
.Where(rh => rh.Material_type == 5)
.Join(dm.Parti_Infos, p => p.Parti_Id, w => w.Parti_Id, (p, w) => new { p.Export_Matrilas_id, p.Material_type, p.Owncom, w.Organization, p.Date })
.Join(dm.Own_Company_Infos, r => r.Owncom, y => y.Company_Id, (r, y) => new { r, y.Organization_Name })
.Join(dm.Material_Types, n => n.r.Material_type, b => b.Id, (n, t) => new { n.r.Export_Matrilas_id, t.Meterial_Name, n.Organization_Name, n.r.Organization, n.r.Date })
.ToList();
DataTable gettbl = ToDataTable(join);
mygride.DataContext = gettbl.DefaultView;
这里我用方法
转成datatable public DataTable ToDataTable<T>(IList<T> data)// T is any generic type
{
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(typeof(T));
DataTable table = new DataTable();
for (int i = 0; i < props.Count; i++)
{
PropertyDescriptor prop = props[i];
// table.Columns.Add(prop.DisplayName,prop.PropertyType);
table.Columns.Add(prop.DisplayName, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
}
object[] values = new object[props.Count];
DataRow row;
foreach (var record in data)
{
row = table.NewRow();
for (int i = 0; i < table.Columns.Count; i++)
{
values[i] = props[i].GetValue(record) != null ? props[i].GetValue(record) : DBNull.Value;
}
table.Rows.Add(row);
}
table.Rows.Add(values);
return table;
}
这是我的 xaml 代码:
<UserControl x:Class="Iqbal_Silks.Export_Tanee_Records"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
Height="700" Width="900">
<UserControl.Resources>
<ResourceDictionary Source="../Themes/Dictionary1.xaml"/>
</UserControl.Resources>
<Grid >
<DataGrid x:Name="mygride" Margin="3,243,10,64" AutoGenerateColumns="False" AlternatingRowBackground="AliceBlue" VerticalContentAlignment="Center" CanUserResizeRows="False" HorizontalContentAlignment="Center" ScrollViewer.PanningMode="VerticalFirst" IsReadOnly="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Export ID" Width="Auto" Binding="{Binding Export_Matrilas_id}"/>
<DataGridTextColumn Header="Materials " Width="Auto" Binding="{Binding Meterial_Name}" />
<DataGridTextColumn Header="Company" Width="Auto" Binding="{Binding Organization_Name}"/>
<DataGridTextColumn Header="Client" Width="Auto" Binding="{Binding Organization}"/>
<DataGridTextColumn Header="Date" Width="Auto" Binding="{Binding Date}"/>
</DataGrid.Columns>
</DataGrid>
<Button Content="Excel Records" x:Name="btnviewchallan_Copy" Style="{StaticResource Hdrclose}" HorizontalAlignment="Left" Margin="616,641,0,0" VerticalAlignment="Top" Width="94" Height="27" Click="BtnviewchallanCopyClick" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Margin="10,644,768,32">
<Button Name="btnFirstPage" Content="<<" Click="btnFirstPage_Click"/>
<Button Name="btnPreviousPage" Content="<" Click="btnPreviousPage_Click"/>
<Label Name="lblPageIndex" Content="{Binding ElementName=root,
Path=PageIndex, UpdateSourceTrigger=PropertyChanged}" Width="Auto"/>
<Label Content="of"/>
<Label Name="lblPageNumber" Content="{Binding ElementName=root,
Path=NumberOfPages, UpdateSourceTrigger=PropertyChanged}" Width="Auto"/>
<Button Name="btnNextPage" Content=">" Click="btnNextPage_Click"/>
<Button Name="btnLastPage" Content=">>" Click="btnLastPage_Click"/>
</StackPanel>
</Grid>
绑定a有两种方法DataGrid
:
可以像您尝试的那样通过 DataContext
属性 来完成:
dataGrid1.DataContext = gettbl.DefaultView;
这里不正确,因为你的 DataContext
在这种情况下是 DataTable
本身 (gettbl) 所以这是正确的:
dataGrid1.DataContext = gettbl;
如果您使用 DataContext
,您还需要将 XAML
中的 ItemsSource
设置为:
<DataGrid ItemsSource="{Binding Path=DefaultView}">
或者另一种方法是直接使用ItemsSource
属性(那么你不需要在XAML
中添加任何额外的代码)
dataGrid1.ItemsSource = gettbl.DefaultView;
此外,我认为您的 ToDataTable
方法有一个错误。
您只向 DataTable
添加了空行,并且它比源集合多了一行。
DataRow row;
foreach (var record in data)
{
row = table.NewRow();
for (int i = 0; i < table.Columns.Count; i++)
{
values[i] = props[i].GetValue(record) != null ? props[i].GetValue(record) : DBNull.Value;
}
// You do not set the row columns anywhere.
table.Rows.Add(row);
// This would work but I'm not sure what you are trying to do.
// table.Rows.Add(values);
}
// You add an extra row here: is this intended?
table.Rows.Add(values);
我也不确定基于指定的对象属性构建数据 table 列是否是个好主意,因为您已经为数据网格定义了列,如果 T
与已定义的列具有不同的属性,那么它们将不匹配,您将看不到任何内容。
也许您已经这样做了,但如果没有考虑使用指定列名的界面或让您的数据网格自动生成列。