【问题标题】:How to databing datagrid with class with collection and modify columns accordingly如何将数据网格与具有集合的类进行数据绑定并相应地修改列
【发布时间】:2016-02-09 10:50:40
【问题描述】:

我有以下课程:

public class MyDimension
{
    public MyDimension()
    {
        obcItemsName = new ObservableCollection<string>();
        obcItemsMeasured = new ObservableCollection<double>();
    }
    public string NameAxisDimension { get; set; }
    public double Nominal { get; set; }
    public double UpperTolerance { get; set; }
    public double LowerTolerance { get; set; }
    public ObservableCollection<string> obcItemsName;
    public ObservableCollection<double> obcItemsMeasured;
}

它的实例被存储到:

ObservableCollection obcmMyDim = new ObservableCollection();

我想将其数据绑定到数据网格

dtgResults.ItemsSource = obcmMyDim

这样数据网格的结果就是这样(用 Excel 制作的)

其中 PART11 PART20 是存储在 obcItemsName 集合中的名称,下面的值存储在 obcItemsMeasured 集合中。

提前谢谢你

【问题讨论】:

    标签: c# wpf multiple-columns observablecollection


    【解决方案1】:

    您可以在这里找到一个很好的教程来展示如何使用 MVVM 设计模式 MVVM TUTORIAL

    【讨论】:

    • 好的,谢谢,我一定会的。但是您的代码无法编译。诀窍在哪里?
    • 我的代码无法在您的项目中编译,因为您没有 viewModel 类,所以正如我已经告诉您的,您必须更改为 MVVM 设计模式。在阅读 MVVM 之前你不会理解它
    【解决方案2】:

    在您的 ViewModel 中:

     private void LoadData()
    {
        obcmMyDim = new ObservableCollection<MyDimension>() {
        new MyDimension() { DimensionProperty = value}, }
    

    然后在 ViewModel Main 构造函数中初始化这个方法

    在 Xaml 代码中

     <datagrid itemsSource="{binding obcmMyDim }" />
    

    【讨论】:

    • 我对 WPF 绑定很陌生。你能解释一下这是如何工作的吗?如前所述,我已经通过 dtgResults.ItemsSource = obcmMyDim 绑定了 dt。然后当添加上面的代码时它不会编译。
    【解决方案3】:

    也请参阅我对您其他问题的回答:https://stackoverflow.com/a/35299063/2141972

    您可以将 ObservableCollection 转换为 System.Data.DataTable。添加您在设计时知道的列,然后循环遍历您仅在运行时知道的列并将它们添加到 DataTable。将您的 DataGrid 绑定到此 DataTable。

    您没有说明 obcItemsName 的每一行是否具有相同的值,所以我编写了一个示例,假设它们没有。有关详细信息,请参阅代码中的 cmets。

    XAML:

    <Window x:Class="WpfApplication2.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApplication2"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <DataGrid ItemsSource="{Binding MyDataTable}" CanUserAddRows="False" />
    </Window>
    

    代码:

    using System.Windows;
    using System.Data;
    
    namespace WpfApplication2
    {
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                // Build list of MyDimensions manually (since I don't have access to your data)
                var Dimensions = CreateData();
                this.DataContext = new MyViewModel(Dimensions);
            }
            public IList<MyDimension> CreateData()
            {
                List<MyDimension> Dimensions = new List<MyDimension>();
                MyDimension d;
                Dimensions.Add(new MyDimension() { NameAxisDimension = "LOC1-X" });
                Dimensions.Add(new MyDimension() { NameAxisDimension = "LOC1-Y" });
                d = new MyDimension() { NameAxisDimension = "LOC1-D" };
                d.obcItemsName.Add("PART11");
                d.obcItemsMeasured.Add(10.0);
                d.obcItemsName.Add("PART20");
                d.obcItemsMeasured.Add(10.1);
                Dimensions.Add(d);
                Dimensions.Add(new MyDimension() { NameAxisDimension = "LOC1-RN" });
                Dimensions.Add(new MyDimension() { NameAxisDimension = "LOC2-X" });
                Dimensions.Add(new MyDimension() { NameAxisDimension = "LOC2-Y" });
                d = new MyDimension() { NameAxisDimension = "LOC2-DF" };
                d.obcItemsName.Add("PART11");
                d.obcItemsMeasured.Add(10.2);
                d.obcItemsName.Add("PART20");
                d.obcItemsMeasured.Add(10.3);
                Dimensions.Add(d);
                Dimensions.Add(new MyDimension() { NameAxisDimension = "LOC2-TP" });
                d = new MyDimension() { NameAxisDimension = "DIST1-M" };
                d.obcItemsName.Add("PART11");
                d.obcItemsMeasured.Add(14.14214);
                d.obcItemsName.Add("PART20");
                d.obcItemsMeasured.Add(14.14215);
                Dimensions.Add(d);
                d = new MyDimension() { NameAxisDimension = "DIST2-M" };
                d.obcItemsName.Add("PART11");
                d.obcItemsMeasured.Add(10.4);
                d.obcItemsName.Add("PART20");
                d.obcItemsMeasured.Add(10.5);
                Dimensions.Add(d);
    
                d = new MyDimension() { NameAxisDimension = "Other Field" };
                d.obcItemsName.Add("PartyLikeIts");
                d.obcItemsMeasured.Add(1999);
                Dimensions.Add(d);
                // etc...
                return Dimensions;
            }
        }
    
        public class MyViewModel
        {
            public DataTable MyDataTable { get; set; }
    
            public MyViewModel(IList<MyDimension> Dimensions)
            {
                // Create a DataTable
                // Add the already known columns - static
                // Add the unknown at designtime columns - dynamic
                // Optionally hook the RowChanged event of the DataTable to push the changes back to Dimensions
    
                MyDataTable = new DataTable();
                // Add the 'static' columns
                MyDataTable.Columns.Add("NameAxisDimension", typeof(string)).ReadOnly = true; // Assuming this is the PK and shouldn't change
                MyDataTable.Columns.Add("Nominal", typeof(double));
                MyDataTable.Columns.Add("UpperTolerance", typeof(double));
                MyDataTable.Columns.Add("LowerTolerance", typeof(double));
                // Add the 'dynamic' columns
                var names = Dimensions.SelectMany(aa => aa.obcItemsName.Select(bb => bb)).Distinct(); // Get a list of the distinct values in all of the obcItemsName collections
                foreach (var name in names)
                    MyDataTable.Columns.Add(name, typeof(double));
                foreach (var dim in Dimensions)
                {
                    List<object> vals = new List<object> { dim.NameAxisDimension, dim.Nominal, dim.UpperTolerance, dim.LowerTolerance }; // static field values
                    foreach (var name in names)
                    {
                        object val = 0.0; // Default value if obcItemsName doesn't have this dynamic field - could also use DBNull.Value
                        int idx = dim.obcItemsName.IndexOf(name);
                        if (idx != -1)
                            val = dim.obcItemsMeasured[idx];
                        vals.Add(val);
                    }
                    MyDataTable.Rows.Add(vals.ToArray());
                }
    
                // If needed, hook the RowChanged event to capture changes and push the changes back to the original collection
                MyDataTable.RowChanged += (s, e) =>
                {
                    if (e.Action == DataRowAction.Change)
                    {
                        // Assumes that "NameAxisDimension" is the PK (and unique to the row)
                        var nameAxisDimension = e.Row.Field<string>("NameAxisDimension");
                        var item = Dimensions.FirstOrDefault(aa => aa.NameAxisDimension == nameAxisDimension);
                        if (item != null)
                        {
                            // Found the entry, update its values
                            // Static fields
                            item.Nominal = e.Row.Field<double>("Nominal");
                            item.UpperTolerance = e.Row.Field<double>("UpperTolerance");
                            item.LowerTolerance = e.Row.Field<double>("LowerTolerance");
                            // Dynamic fields
                            foreach (var name in names)
                            {
                                int idx = item.obcItemsName.IndexOf(name);
                                if (idx != -1)
                                {
                                    item.obcItemsMeasured[idx] = e.Row.Field<double>(name);
                                }
                                else
                                {
                                    // This row doesn't have that name in obcItemsName. Add it?
                                    item.obcItemsName.Add(name);
                                    item.obcItemsMeasured.Add(e.Row.Field<double>(name));
                                }
                            }
                        }
                    }
                };
            }
        }
    
        public class MyDimension
        {
            public MyDimension()
            {
                obcItemsName = new ObservableCollection<string>();
                obcItemsMeasured = new ObservableCollection<double>();
            }
            public string NameAxisDimension { get; set; }
            public double Nominal { get; set; }
            public double UpperTolerance { get; set; }
            public double LowerTolerance { get; set; }
            public ObservableCollection<string> obcItemsName;
            public ObservableCollection<double> obcItemsMeasured;
        }
    }
    

    截图:

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-31
      • 2011-05-14
      • 1970-01-01
      相关资源
      最近更新 更多