Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 数据绑定到具有未知列数的网格_C#_Wpf_Data Binding - Fatal编程技术网

C# 数据绑定到具有未知列数的网格

C# 数据绑定到具有未知列数的网格,c#,wpf,data-binding,C#,Wpf,Data Binding,如何绑定到列数未知的WPF网格 我有一个类,可以返回列数和列名等,以及将绑定到每行的项。基本上,我想做DataTable在不使用DataTable的情况下可以做的事情。必须有一个我需要实现的接口或类似的东西。如果您的对象(DataContext)实现IEnumerable,datagrid将能够吸入对象并显示记录。只需将AutoGenerateColumns设置为true,它将根据您传递的对象为您生成列。已更新 最好的解决方案是使用匿名类型。它工作正常,请参见以下概念证明: <Windo

如何绑定到列数未知的WPF网格

我有一个类,可以返回列数和列名等,以及将绑定到每行的项。基本上,我想做DataTable在不使用DataTable的情况下可以做的事情。必须有一个我需要实现的接口或类似的东西。

如果您的对象(DataContext)实现IEnumerable,datagrid将能够吸入对象并显示记录。只需将AutoGenerateColumns设置为true,它将根据您传递的对象为您生成列。

已更新
最好的解决方案是使用
匿名类型
。它工作正常,请参见以下概念证明:

<Window x:Class="AnonymousTypes.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" Loaded="OnWindowLoaded">
    <Grid>
        <DataGrid Name="MyDataGrid" ItemsSource="{Binding}" AutoGeneratedColumns="OnMyDataGridAutoGeneratedColumns">

        </DataGrid>
    </Grid>
</Window>

背后的代码:

using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace AnonymousTypes
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        public class Employee
        {
            public int Id { get; set; }
            public string Code { get; set; }
            public string Name { get; set; }
            public int Job { get; set; }
            public string Address { get; set; }
        }

        private ObservableCollection<Employee> _empCollection;

        private void OnWindowLoaded(object sender, RoutedEventArgs e)
        {
            // Generate test data
            _empCollection =
                new ObservableCollection<Employee>
                    {
                        new Employee {Id = 234, Code = "E041", Name = "Employee1", Job = 1, Address = "..."},
                        new Employee {Id = 245, Code = "E701", Name = "Employee2", Job = 3, Address = "..."},
                        new Employee {Id = 728, Code = "E001", Name = "Employee3", Job = 9, Address = "..."},
                        new Employee {Id = 663, Code = "E051", Name = "Employee4", Job = 7, Address = "..."},
                    };
            // Notice that here you can chose the column you want,
            // and it can be variable with each query depending on your needs
            // Just add the columns you need to the anonymous type
            DataContext =
                (from i in _empCollection
                 select new {TheCode =  i.Code, TheName = i.Name, TheAddress = i.Address }).ToList();
        }

        private void OnMyDataGridAutoGeneratedColumns(object sender, EventArgs e)
        {
            // Now you can change the column names as you need
            MyDataGrid.Columns[0].Header = "Header 1 [Code]";
            MyDataGrid.Columns[1].Header = "Header 2 [Name]";
            MyDataGrid.Columns[2].Header = "Header 3 [Address]";
        }
    }
}
使用系统;
使用System.Collections.ObjectModel;
使用System.Linq;
使用System.Windows;
命名空间匿名类型
{
/// 
///MainWindow.xaml的交互逻辑
/// 
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
}
公营雇员
{
公共int Id{get;set;}
公共字符串代码{get;set;}
公共字符串名称{get;set;}
公共int作业{get;set;}
公共字符串地址{get;set;}
}
私人可观察收集(empu collection);;
WindowLoaded上的私有void(对象发送方,RoutedEventArgs e)
{
//生成测试数据
_EMP收集=
新可观测集合
{
新员工{Id=234,Code=“E041”,Name=“Employee1”,Job=1,Address=“…”},
新员工{Id=245,Code=“E701”,Name=“Employee2”,Job=3,Address=“…”},
新员工{Id=728,Code=“E001”,Name=“Employee3”,Job=9,Address=“…”},
新员工{Id=663,Code=“E051”,Name=“Employee4”,Job=7,Address=“…”},
};
//请注意,在这里您可以选择所需的列,
//根据您的需要,它可以随每个查询而变化
//只需将所需的列添加到匿名类型
数据上下文=
(来自我的收藏)
选择new{TheCode=i.Code,TheName=i.Name,TheAddress=i.Address}).ToList();
}
私有void OnMyDataGridAutoGeneratedColumns(对象发送方,事件参数e)
{
//现在,您可以根据需要更改列名
MyDataGrid.Columns[0]。Header=“Header 1[Code]”;
MyDataGrid.Columns[1].Header=“Header 2[Name]”;
MyDataGrid.Columns[2].Header=“Header 3[地址]”;
}
}
}

您可以在数据绑定完成后,使用
自动生成列
事件更改列标题。

我最后使用SyncFusion网格控件解决了这个问题。我发现内置网格,以及市场上几乎所有的网格,都非常倾向于将一行作为从数据库返回的对象

如果偏离此模型,则大多数网格将变得无用,或者至少非常难以使用。在我的例子中,数据库中的每一行代表一个单元格。我在所有网格中遇到的关键问题是获得一个WPF模板来处理未绑定的数据。SyncFusion网格是我能找到的唯一一个可以同时使用这两个功能的网格(
ubound
data和data templates)


我还发现flexgrid可以解决这个问题,尽管在这方面有点困难。

谢谢您的回复。问题是仍然需要将列编译到应用程序中。在查询数据库之前,我不知道列名。不,问题是,我的解决方案中最重要的部分是最后三行,其余的只是展示我的概念证明。在最后三行中,请注意,我从Employee类中动态选择了五个属性中的三个,您也可以这样做,当然,您有一些结果集,其中包含对数据库的查询结果,因此,您可以像我这样做,根据某些条件从结果集中动态选择所需的列。嗨,Mohammed,这对我不起作用,因为我事先不知道列名。在您提供的代码中,编译器将创建一个具有代码、名称和地址属性的类。这不是动态的,而是硬编码到应用程序中的东西。我所说的动态是对列本身的选择。关于列标题,无法为数据绑定数据网格动态设置它们,您必须在数据绑定完成后更改标题,请参阅更新的解决方案。再次感谢Mohammed。问题是用户可以在数据库中输入10、20或50列。在您的示例中,您仍然硬编码为3列,这些列都硬编码为类中的某些属性。标题可以更改,但不会更改数据的来源。想象一下,我从这样一门课开始:谢谢你的回答。我认为这不会解决问题,因为在查询数据库之前我不知道列名。另外,如果集合是空的,那么我将不会得到任何列。在我的例子中,列将是用户可以命名为Day1、Day2等或mon、tue的天数。行将是时隙8-9am、9-10am等。假设您为特定用户获得10列。。当返回结果时(假设在数据表中),可以根据返回的列数运行循环。。为什么要知道返回了多少列?除了不使用datatable之外,我想这样做。我正在使用LINQtoEntities获取数据