【问题标题】:Bind DataGrid to DataTable haveing columns of type Custom Objects将 DataGrid 绑定到具有自定义对象类型的列的 DataTable
【发布时间】:2014-08-13 01:27:43
【问题描述】:

我有 DataTable,我正在尝试将 DataGrid 与 DataTable 绑定。但是我的列不是简单类型的,它们是自定义对象。

public class Node
    {
        public string Name { get; set; }
        public int Id { get; set; }

        public Node(string name, int id)
        {
            Name = name;
            Id = id;
        }
    }

public class NodeBool
    {
        public bool Name { get; set; }
        public int Id { get; set; }

        public Node(bool name, int id)
        {
            Name = name;
            Id = id;
        }
    }


     <DataGrid Name="data1" AutoGenerateColumns="True" ItemsSource="{Binding MyDataTable}" />

在执行之前这些列是未知的。它们在运行时基于列表已知,广告列表用于在数据表中添加列

当我将它绑定到数据网格时,会显示列全类名下的每一行。我想将它绑定到类属性,并根据属性复选框(布尔)或文本框(字符串)应该显示。

我正在关注 MVVM 模型。

【问题讨论】:

    标签: c# wpf mvvm datagrid datatable


    【解决方案1】:

    你必须在下面提到的代码中使用。

    public class NodeBool
    {
        public bool Name { get; set; }
        public int Id { get; set; }
    
        public NodeBool(bool name, int id)
        {
            Name = name;
            Id = id;
        }
    }
    

    然后你必须像声明 ObservableCollection

     private ObservableCollection<NodeBool> _MyData=new ObservableCollection<NodeBool>();
    
        public ObservableCollection<NodeBool> MyData
        {
            get { return _MyData; }
            set { _MyData = value; RaisePropertyChanged("MyData"); }
        }
    

    然后你必须在collecton中输入值

      MyData.Add(new NodeBool(true,1));
    

    你的数据网格看起来像

    <DataGrid ItemsSource="{Binding MyData}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridCheckBoxColumn MinWidth="150" Header="Name" Binding="{Binding Name}"/>
                <DataGridTextColumn MinWidth="180" Header="Id" Binding="{Binding Id}"/>
            </DataGrid.Columns>
        </DataGrid>
    

    【讨论】:

    • 我需要使用我的数据表。我的 DataTable 列是根据用户输入决定的,可以是任意数量。因此它们应该在运行时创建,而不是在 XAML 中提及。我的意思是我的 DataTable 列被声明为这样 MyDataTable.Columns.Add("xyz", typeof(NodeBool)) 并且在该列中我想要一个显示属性 NodeBool.Name 的复选框
    【解决方案2】:

    你可以做的是改变你的代码喜欢这个

     <DataGrid Name="data1" AutoGenerateColumns="True" ItemsSource="{Binding Path=.}" />
    

    在后面的代码中你可以做的是

    创建一个数据表并在其中添加列并在其中添加数据

     DataTable dataTable=new DataTable();
    

    //for循环使用反射获取对象的所有属性 dataTable.Columns.Add(item.Name);

    //获取dataTable中所有信息的for循环

    DataRow  dr;
    

    //像这样添加每个值

    dr=dataTable.NewRow();

    dr[propertyName] = object.Propertyname;

    dataTable.Rows.Add(dr);
       dataTable.AcceptChanges();
    

    // 然后将该表绑定到数据网格。

       data1.ItemSource = dataTable.DefaultView 
    

       data1.DataContext = dataTable; 
    

    确切的代码库如下所示 在这里,我假设您的信息来源将是类型类(节点类)的列表,它将将其转换为相应的数据表并显示数据网格

    public void ConvertListToDataTable()
    {
        DataTable dt = new DataTable();
        Node obj = new Node();
        //here obj is instance of your node type
        foreach (var item in obj.GetType().GetProperties())
        {
            dt.Columns.Add(item.Name);
        }
    
        List<Node> objDetails = new List<Node>();
        Node objNode = new Node();
        objNode.Name = true;
        objNode.Id = "Test B";
    
        Node objNode1 = new Node();
        objNode1.Name = false;
        objNode1.Id = "Test B 1";
    
        objDetails.Add(objNode);
        objDetails.Add(objNode1);
    
        DataRow dr;
        for (int i = 0; i < objDetails.Count; i++)
        {
            dr = dt.NewRow();
            foreach (var item in obj.GetType().GetProperties())
            {
                dr[item.Name] = objDetails[i].GetType().GetProperty(item.Name).GetValue(objDetails[i], null);
            }
            dt.Rows.Add(dr);
        }
    
        dt.AcceptChanges();
        data1.ItemsSource = dt.DefaultView;
    }
    

    【讨论】:

    • 在此方法中,我将属性添加为行中的元素。我需要将 Object 作为一个整体添加,这样当我从 Datatable 中获取它时,我也应该能够获取 Id 属性。
    • 我添加了可能对您有所帮助的新代码,并且它使用了反射,因此将来任何数量的属性都将添加到节点类中,它将自动处理并显示在前端,无需手动您需要为此编写代码。
    猜你喜欢
    • 1970-01-01
    • 2011-05-03
    • 2013-12-22
    • 2012-11-16
    • 2019-01-28
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多