C# 以编程方式将列添加到datagrid而不是编译

C# 以编程方式将列添加到datagrid而不是编译,c#,wpf,datagrid,multiple-columns,C#,Wpf,Datagrid,Multiple Columns,这是本书的延续 我看过这个帖子: datagrid就是这样: <DataGrid Name="dtgResults" Background="Transparent" AutoGenerateColumns="False"/> 在这种情况下,一切似乎都正常工作,但当我将其放入解决方案中时,它无法编译: 谁能解释一下原因吗 ---编辑--- 我现在意识到我误解了上面链接中的内容。 简而言之,我有一个绑定到可观察集合的数据网格。 我必须再添加两列。如何做到这一点 ---编辑2

这是本书的延续

我看过这个帖子:

datagrid就是这样:

<DataGrid Name="dtgResults" Background="Transparent" AutoGenerateColumns="False"/>

在这种情况下,一切似乎都正常工作,但当我将其放入解决方案中时,它无法编译:

谁能解释一下原因吗

---编辑---

我现在意识到我误解了上面链接中的内容。 简而言之,我有一个绑定到可观察集合的数据网格。 我必须再添加两列。如何做到这一点

---编辑2----用于CBreeze

 dtgResults.ItemsSource = obcmMyDim;<--------previous data here
 DataGridTextColumn textColumn1 = new DataGridTextColumn();
 textColumn1.Header = "AAA1";
 textColumn1.Binding = new Binding("AAA1");

 DataGridTextColumn textColumn2 = new DataGridTextColumn();
 textColumn2.Header = "AAA2";
 textColumn2.Binding = new Binding("AAA2");

 Application.Current.Dispatcher.BeginInvoke(new ThreadStart(() => dtgResults.Columns.Add(textColumn1)));
 Application.Current.Dispatcher.BeginInvoke(new ThreadStart(() => dtgResults.Columns.Add(textColumn2)));

 dtgResults.Items.Add(new { AAA1 = "Col1Row1", AAA2 = "Col2Row1"});
 dtgResults.Items.Add(new { AAA1 = "Col1Row2", AAA2 = "Col2Row2" });
dtgResults.ItemsSource=obcmMyDim;dtgResults.Columns.Add(textColumn1));
Application.Current.Dispatcher.BeginInvoke(新的ThreadStart(()=>dtgResults.Columns.Add(textColumn2));
添加(新的{AAA1=“Col1Row1”,AAA2=“Col2Row1”});
添加(新的{AAA1=“Col1Row2”,AAA2=“Col2Row2”});
---编辑3---用于JH 简言之,我有一个绑定到datagrid的可观察集合,它生成以下输出:

然后,我使用您的方法添加列:

var names = obcmMyDim.First().obcItemsName; // All entries must have the same list of obcItemsName and in the same order
    for (int i = 0; i < names.Count; i++)
    {
      DataGridTextColumn c = new DataGridTextColumn();
      c.Header = names[i];

      var b = new Binding();
      string str = string.Format("obcmMyDim.obcItemsMeasured[{0}]", i);
      b.Path = new PropertyPath(str);
      b.Mode = BindingMode.TwoWay;

      c.Binding = b;

      dtgResults.Columns.Add(c);
    }
var name=obcmMyDim.First().obcItemsName;//所有条目必须具有相同的obcItemsName列表,且顺序相同
for(int i=0;i
至于绑定数组

绑定str是“obcmMyDim.obcItemsMeasured[0]”…1…n

但我得到的是列在那里,但它们是空的


它不会编译,因为您使用了
ItemCollection
。我认为您并没有像在Response from link中那样创建自己的类,而是使用了
System.Windows.Controls.ItemCollection
,这在本例中无法使用

dtgResults.Columns.Add(new DataGridTextColumn { Header = "a.1"});
dtgResults.Columns.Add(new DataGridTextColumn { Header = "a.2"});
编辑:

 for (int i = 1; i <= 10; i++)
 {
     dtgResults.Items.Add(new { a.1 = "Test" + i, a.2 = "Test" + i});
 }

for(int i=1;i您可以绑定到数组中的一个项,但必须确保所有数组都是相同的(相同的字段,以相同的顺序,以便它们的索引是一致的)。下面是一个基于您的另一个问题的示例

请注意,必须将字段obcItemsMeasured更改为属性,因为绑定需要属性(而不是字段)

XAML:


代码:

使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用System.Linq;
使用System.Windows;
使用System.Windows.Controls;
使用System.Windows.Data;
命名空间WpfApplication2
{
公共部分类主窗口:窗口
{
公共主窗口()
{
初始化组件();
//手动生成MyDimensions列表(因为我无法访问您的数据)
var obcmMyDim=新的ObservableCollection(CreateData());
dtgResults.ItemsSource=obcmMyDim;
var names=obcmMyDim.First().obcItemsName;//所有条目必须具有相同的obcItemsName列表,且顺序相同

对于(int i=0;i错误消息是什么?我建议使用数据绑定,而不是逐个添加项。如果您来自WinForms,您应该重新考虑将控件链接到实际数据的方式。我无法做到这一点。我已经在此处发布了标题问题,可以,但如何添加列的值?@Patrick add a new item?
dtgResults.Items.Add(new{a.1=“Test1”,a.2=“Test2”});
该列根据行数由多个值组成。因此,我很困惑如何将其作为单个值添加???我希望类似于a.1={“Col1Row1”,“Col1Row2”…)很好!!!我们越来越近了。唯一的问题是它没有添加列,而是删除了所有列,然后只添加新列。@Patrick是这样通过编程将旧列也添加进来的?如果你不使用
数据绑定
,我想这是你必须做的,因此为什么这么多人建议使用
数据绑定
。你应该不需要将值添加到循环中,因此
dtgResults.Items.add(新的{a.1=“Test”+i,a.2=“Test”+i,col3=“Test”+i,col4=“Test”+i等)
谢谢您的帮助。我确信所有数组都具有相同的长度。您的代码产生的问题与我在CBreeze的解决方案中注意到的问题相同。请查看我的编辑。您是否将ObjectemsMeasured更改为属性?如果它只是一个成员字段,则无法使用。必须是一个属性才能使用绑定。
<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 x:Name="dtgResults" CanUserAddRows="False" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding NameAxisDimension}" Header="NameAxisDimension" />
            <DataGridTextColumn Binding="{Binding Nominal}" Header="Nominal" />
            <DataGridTextColumn Binding="{Binding UpperTolerance}" Header="UpperTolerance" />
            <DataGridTextColumn Binding="{Binding LowerTolerance}" Header="LowerTolerance" />
        </DataGrid.Columns>
    </DataGrid>
</Window>
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.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 obcmMyDim = new ObservableCollection<MyDimension>(CreateData());
            dtgResults.ItemsSource = obcmMyDim;

            var names = obcmMyDim.First().obcItemsName; // All entries must have the same list of obcItemsName and in the same order
            for (int i=0; i<names.Count; i++)
            {
                DataGridTextColumn c = new DataGridTextColumn();
                c.Header = names[i];

                var b = new Binding();
                b.Path = new PropertyPath(string.Format("obcItemsMeasured[{0}]", i)); // Binding is based on index into array, thats why all entries have to have the same dynamic fields
                b.Mode = BindingMode.TwoWay;

                c.Binding = b;

                dtgResults.Columns.Add(c);
            }

        }
        public IList<MyDimension> CreateData()
        {
            List<MyDimension> Dimensions = new List<MyDimension>();
            string[] names = new string[] { "PART11", "PART20" }; // They must all have the same obcItemsName/obcItemsMeasured entries, and in the same order
            Dimensions.Add(CreateItem("LOC1-X", names, 0, 0));
            Dimensions.Add(CreateItem("LOC1-Y", names, 0, 0));
            Dimensions.Add(CreateItem("LOC1-D", names, 10.0, 10.1));
            Dimensions.Add(CreateItem("LOC1-RN", names, 0, 0));
            Dimensions.Add(CreateItem("LOC2-X", names, 0, 0));
            Dimensions.Add(CreateItem("LOC2-Y", names, 0, 0));
            Dimensions.Add(CreateItem("LOC1-DF", names, 10.2, 10.3));
            Dimensions.Add(CreateItem("LOC2-TP", names, 0, 0));
            Dimensions.Add(CreateItem("DIST1-M", names, 14.14214, 14.14215));
            Dimensions.Add(CreateItem("DIST2-M", names, 10.4, 10.5));
            // etc...
            return Dimensions;
        }
        public MyDimension CreateItem(string name, string[] names, params double[] values)
        {
            var d = new MyDimension();
            d.NameAxisDimension = name;
            for (int i = 0; i < names.Length; i++)
            {
                d.obcItemsName.Add(names[i]);
                d.obcItemsMeasured.Add(values[i]);
            }
            return d;
        }
    }
    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 { get; set; } // Has to be a property since it is used in the binding
    }
}