向DataGrid中的特定列添加数据

15 浏览
0 Comments

向DataGrid中的特定列添加数据

我想在按钮点击事件中创建一个新列,并且仅向该新列添加值。是否可行?该列可能会有一些行,具体取决于报价中的项目数量。

我目前已经实现的部分:

存储所有信息的类:

public class ViewQuoteItemList
{
    ...
    public double SupplierCost { get; set; }
    ...
}

我可以创建列并将其绑定到我的`ViewQuoteItemList`类:

DataGridTextColumn columnFeedbackSupplier = new DataGridTextColumn();
columnFeedbackSupplier.Binding = new Binding("SupplierCost");
// 列的标题从下拉列表框中选择添加到数据网格的公司名称中获取
columnFeedbackSupplier.Header = (cmbFeedbackSelectSupplier.SelectedItem as DisplayItems).Name;

然后,我从不同的数据网格获取我的报价项目,并将它们添加到我想要添加新列及其值的第二个数据网格中:

IList list = dgFeedbackAddCost.SelectedItems as IList;
IEnumerable items = list.Cast();
var collection = (from i in items
                  let a = new ViewQuoteItemList { SupplierCost = 0 }
                  select a).ToList();

最后,我将新列添加到第二个数据网格,并将`collection`设置为数据网格的`ItemSource`:

dgFeedbackSelectSupplier.Columns.Add(columnFeedbackSupplier);
dgFeedbackSelectSupplier.ItemsSource = collection;

我的问题是,一旦我编辑了一个供应商的单元格数据,整行的所有单元格都会更新为相同的值,因为它们都绑定到同一个类/项目源。这个问题可以修复吗?

编辑:

“整行的所有单元格都会更新”意味着每次我在一行的一个单元格中插入一个值时,该行的每个单元格都会更新为相同的值。下面是一些图片展示我所说的。我想编辑所有的数据,这些都发生在我的第二个数据网格(dgFeedbackSupplier)上。

这里,我添加了两个公司和我想要比较价格的4个项目。现在,我想点击公司下面的单元格并为特定项目添加一个值。

[图片链接](https://i.stack.imgur.com/71PSk.jpg)

我双击一个单元格来编辑/更改值。

[图片链接](https://i.stack.imgur.com/Xcpbf.jpg)

然后,当我在选择的单元格中更改值时,同一行中其他公司的该特定项目的值也会更新为相同的值。

[图片链接](https://i.stack.imgur.com/odmqY.jpg)

这就是我的问题,我需要仅更改那个单元格的值,而不是整行。

编辑2:

如何将`collection`转换为`ExpandoObject`?

var collection = (from i in items
                  let a = new ViewQuoteItemList { Item = i.Item, Supplier = 25 }
                  select a).ToList();

编辑3:

我的XAML:


    
        
    

这是我的整个方法的代码,其中添加了列并从其他数据网格获取项目:

private void btnFeedbackSelectSupplier_Click(object sender, RoutedEventArgs e)
{
    supplier.Id = (cmbFeedbackSelectSupplier.SelectedItem as DisplayItems).Id;// 暂时未使用
    supplier.Name = (cmbFeedbackSelectSupplier.SelectedItem as DisplayItems).Name;
    DataGridTextColumn columnFeedbackSupplier = new DataGridTextColumn();
    columnFeedbackSupplier.Binding = new Binding("Supplier") { Mode = BindingMode.TwoWay };
    columnFeedbackSupplier.CanUserReorder = true;
    columnFeedbackSupplier.CanUserResize = true;
    columnFeedbackSupplier.IsReadOnly = false;
    columnFeedbackSupplier.Header = supplier.Name;
    dgFeedbackAddCost.SelectAll();
    IList list = dgFeedbackAddCost.SelectedItems as IList;
    IEnumerable items = list.Cast();
    var collection = new List();
    foreach (var i in items)
    {
        dynamic a = new ExpandoObject();
        a.Id = (cmbFeedbackSelectSupplier.SelectedItem as DisplayItems).Id;
        a.Item = i.Item;
        a.Supplier = 25;
        collection.Add(a);
    }
    dgFeedbackSelectSupplier.Columns.Add(columnFeedbackSupplier);
    dgFeedbackSelectSupplier.ItemsSource = collection;
}

0
0 Comments

问题的出现原因:

这个问题的出现是因为用户想要在一个DataGrid中的特定列中添加数据,但是不知道如何实现。

解决方法:

解决方法是使用Microsoft Dynamics的ExpandoObject。用户需要创建一个List,这实际上是一个Dictionary,其中键是属性名,值是属性值。然后将ViewQuoteItem中的所有属性添加到这个新的对象中,当需要添加列时,可以在对象中添加另一个属性。然后更新视图,就可以看到新添加的列出现在网格中。

用户可以使用Expando的简单方法进行操作,例如:

var dynamicItem = New ExpandoObject();

dynamicItem.Item = "Test";

dynamicItem.BarlwoodCityDeep = (int)350;

用户也可以将dynamicItem视为字典进行操作,例如:

IDictionary dynamicDict = dynamicItem;

dynamicDict.Add("MyNewProperty","MySomeValue")

建议用户编写一个将dataList映射到新expandoList并将其绑定到视图的方法,并确保在WPF中使用自动生成列,以便新添加的列可见。

用户还可以查看类似情况下为我工作的解决方案。

如果用户对dynamics不熟悉,可能会觉得有点棘手,但是使用Expandos真的很酷,使用它们非常方便。

将ViewQuoteItemList转换为Expando的代码示例:

var collection = new List();

foreach (var i in items)

{

dynamic a = new ExpandoObject();

a.Item = i.item;

a.Supplier = 25;

collection.Add(a);

}

相关文章:

用户可以在这里找到相关文章。

感谢提供答案!一旦我把所有的东西都搞定了,我会立即告诉你的。

ExpandoObjects真的很酷(或者我到目前为止学到的东西),但是我遇到的一个问题是:“All the properties in ViewQuoteItem are added to this new Object”。我如何将我的ViewQuoteItemList设置为ExpandoObject?

我已经添加了一个简化的代码来将您的对象转换为Expando。

非常感谢您迄今为止提供的所有帮助。不过我还有几个问题。对此我感到抱歉,但是看起来您的编码确实引导我朝着正确的方向前进。我的新列已经正确添加,我可以看到每个公司下的项目的显示值为25。我目前的主要问题是,这些值仍然与网格中的每个公司相连,当我更改一个值时,选定行中的所有值都会更改。所以我的问题是,您能否展示给我如何将每个添加的列分开,使其拥有自己的值?

对于给您带来的不便和我的回复速度慢,我感到很抱歉,但是我需要这么长时间来弄清楚一切,因为我对C#编程还非常陌生,对于您在答案中试图向我解释的内容我并不完全理解。

我已经添加了我的XAML,并插入了整个方法,所有事情都应该在那里发生。

您需要在XAML中将集合绑定到网格,请阅读有关数据网格绑定的内容,然后处理ColumnAutoGeneratingEvent并在其中添加列。

0
0 Comments

问题的原因是无法使用集合来绑定第二个DataGrid,因为视图是动态的,可能具有可变的列数。解决方法是使用DataTable作为DataGrid的数据源。不要在DataGrid中添加列,而是在DataTable中添加列,并在Grid中自动生成列。

一个将数据源(任何类型)转换为DataTable的方法是:

public static DataTable DataGridtoDataTable(DataGrid dg)
{
    dg.SelectAllCells();
    dg.ClipboardCopyMode = DataGridClipboardCopyMode.IncludeHeader;
    ApplicationCommands.Copy.Execute(null, dg);
    dg.UnselectAllCells();
    String result = (string)Clipboard.GetData(DataFormats.CommaSeparatedValue);
    string[] Lines = result.Split(new string[] { "\r\n", "\n" }, StringSplitOptions.None);
    string[] Fields;
    Fields = Lines[0].Split(new char[] { ',' });
    int Cols = Fields.GetLength(0);
    DataTable dt = new DataTable();
    for (int i = 0; i < Cols; i++)
        dt.Columns.Add(Fields[i].ToUpper(), typeof(string));
    DataRow Row;
    for (int i = 1; i < Lines.GetLength(0) - 1; i++)
    {
        Fields = Lines[i].Split(new char[] { ',' });
        Row = dt.NewRow();
        for (int f = 0; f < Cols; f++)
        {
            Row[f] = Fields[f];
        }
        dt.Rows.Add(Row);
    }
    return dt;
}

然后,在需要在DataGrid中添加列的时候,通过迭代集合在表中添加列来填充数据表中的列。

这个问题没有简单的解决方法,因为你的场景是独特的,只有动态结构才能满足你的需求。使用DataTable,每个单元格都将绑定到唯一的实体。更改DataGrid单元格时,只有一个单元格会被更新(与集合不同,多个单元格绑定到同一个属性)。

在操作期间,全局剪贴板数据会被修改,最好在操作之前弹出当前剪贴板数据,并在操作后将其推回剪贴板。

感谢你的答案!我一有进展就会向你更新。

0
0 Comments

问题的出现的原因:

问题出现的原因是在尝试使用一个表格视图组件来显示非表格数据。实际上,所拥有的数据是层次结构的数据,而不是表格形式的数据。

解决方法:

解决方法是创建一个新的视图,将层次结构的数据填充并转换为表格形式。为了在XAML中能够选择适当的数据模板,可以使用虚拟类来填充空槽。解决方法遵循MVVM+XAML的方式,避免使用任何自定义代码,并将所有内容保持在MVVM+XAML方式中。通过使用MVVMLight中的messenger类来更新新视图,手动调用RaisePropertyChanged事件。在XAML中使用ItemsControl和UniformGrid组件创建表格视图。完整的解决方案可以在GitHub上找到。

文章如下:

从我理解的情况来看,你有供应商,这些供应商有商品。你可以添加新的供应商。我假设供应商可能没有所有的商品(为了增加挑战性 :))。

你想以表格视图的方式呈现这个数据结构。

问题在于你试图使用一个表格视图组件来显示非表格形式的数据。实际上,你拥有的是一个层次结构的数据。在继续解决方案之前,这里有一些屏幕截图。

(插入图片)

基本上,我在这里创建了基于层次结构数据的新视图,填充了空槽,并将其转换为表格形式。我使用虚拟类来填充空槽,这样我就可以在XAML中轻松选择适当的数据模板。我避免使用任何自定义代码,将所有内容都保持在MVVM+XAML方式中。因此,绑定等都按预期工作。

当集合发生变化时,必须更新新的视图,所以我使用了MVVMLight中的messenger类来实现简便,并手动调用RaisePropertyChanged事件。

在XAML中,我使用ItemsControl和UniformGrid组件创建了表格视图。

我在GitHub上放置了完整的解决方案。

如果出现构建错误,请右键单击解决方案并还原NuGet包。

非常感谢你的回答。然而,有点晚了。我已经找到了在我的数据表格中如何做到这一点的方法。我将在今天晚些时候发布答案,如果有机会的话!再次感谢你的努力。

没问题,这是一个有趣的问题。我觉得以后可能会用到。

太好了,我发布了一个答案,展示了我的代码以及我是如何解决这个谜题的。希望它能在将来对你有所帮助。

0