如何使用集合对datagrid进行数据绑定并相应地修改列

时间:2016-02-09 10:50:40

标签: c# wpf multiple-columns observablecollection

我有以下课程:

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&LT; MyDimension&GT; obcmMyDim = new ObservableCollection&lt; MyDimension&gt;();

我想用

将数据绑定到数据网格
  

dtgResults.ItemsSource = obcmMyDim

以便数据网格结果(使用Excel制作)

enter image description here

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

提前谢谢

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

在ViewModel中:

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

然后在ViewModel Main构造函数

中初始化此方法

和Xaml代码

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

答案 2 :(得分:0)

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

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

你没有说明obcItemsName是否对每一行都有相同的值,所以我编写了一个例子,假定它们没有。有关详细信息,请参阅代码中的注释。

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

截图:

enter image description here