【问题标题】:Programmatically add columns to datagrid not compiling以编程方式将列添加到未编译的数据网格
【发布时间】:2016-02-09 14:51:04
【问题描述】:

这是继续

OnEvent datagrid column add fail

我看过这个帖子:

How to add Data to a WPF datagrid programatically

数据网格就是这样的:

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

其中一切似乎都运行良好,但是当我将它放入我的解决方案时它无法编译:

谁能解释一下为什么?

---编辑---

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

---EDIT2---- 用于 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" });

---编辑 3--- 对于 JH 所以简而言之,我有绑定到数据网格的可观察集合进行以下输出:

然后我用你的方法添加列:

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

至于绑定数组

绑定 str 为 "obcmMyDim.obcItemsMeasured[0]" ...1....n

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

【问题讨论】:

  • 错误信息是什么?
  • 我建议使用 DataBinding 而不是逐个添加项目。如果您来自 WinForms,则应该重新考虑将控件链接到实际数据的方式。
  • 我做不到。我已经在这里发布了问题stackoverflow.com/questions/35290099/…

标签: c# wpf datagrid multiple-columns


【解决方案1】:

你有没有尝试过类似的东西;

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

【讨论】:

  • 对于标题很好,但如何添加列的值?
  • @Patrick 添加新项目? dtgResults.Items.Add(new { a.1 = "Test1", a.2 = "Test2" });
  • 该列根据行数由多个值组成。所以我很困惑如何将它添加为单个值???我希望像 a.1 = {"Col1Row1", "Col1Row2",.....}
  • 非常好!!!我们越来越近了。唯一的问题是它没有添加列,它删除了所有列,然后只添加了新列。
  • @Patrick 所以也以编程方式添加旧的吗?如果您不使用DataBinding,我认为这是您必须做的,因此为什么这么多人建议使用DataBinding。你只需要将值添加到循环中,所以dtgResults.Items.Add(new { a.1 = "Test" + i, a.2 = "Test" + i, col3 = "Test" + i, col4 = "Test" +i etc etc});
【解决方案2】:

因为你使用了ItemCollection,所以它没有编译。我认为您没有像从链接中回答那样创建自己的类,而是使用了System.Windows.Controls.ItemCollection,在这种情况下不能使用。

【讨论】:

    【解决方案3】:

    您可以绑定到数组中的项目,但您必须确保所有数组都相同(相同的字段,以相同的顺序,以便它们的索引是一致的)。这是基于您的其他问题的示例。

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

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

    截图:

    【讨论】:

    • 感谢您的帮助。我很安全,因为所有阵列都具有相同的长度。您的代码产生了与 CBreeze 解决方案相同的问题。请查看我的编辑。
    • 您是否将 obcItemsMeasured 更改为属性?如果它只是一个成员字段,它将不起作用。必须是绑定工作的属性。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-23
    • 2013-04-28
    • 2013-11-03
    • 1970-01-01
    • 2011-04-22
    相关资源
    最近更新 更多