简体   繁体   English

使用动态列将行绑定到 DataGrid

[英]Binding Rows to DataGrid with Dynamic Columns

I am creating a Retail Clothing POS System and am wanting to display items that are associated with a style in a specially formatted DataGrid.我正在创建一个零售服装 POS 系统,并且想要在特殊格式的 DataGrid 中显示与样式相关联的项目。

Such as:如:

┌───────┬───┬───┬───┬───┬───┐
│ Color │ S │ M │ L │ X │ 2 │
├───────┼───┼───┼───┼───┼───┤
│ Red   │ 2 │ 2 │ 2 │ 0 │ 1 │
│ Blue  │ 0 │ 1 │ 2 │ 0 │ 0 │
│ Pink  │ 0 │ 2 │ 1 │ 1 │ 1 │
└───────┴───┴───┴───┴───┴───┘

I have the columns on the grid added at runtime based on the sizes in the style.我在运行时根据样式中的大小添加了网格上的列。 The only issue I am having is when I try to Bind the Sizes property to a column.我遇到的唯一问题是当我尝试将 Sizes 属性绑定到列时。

private void SetColumns()
{

    ObservableCollection<DataGridColumn> columns =
        new ObservableCollection<DataGridColumn>();

    var color_col = new DataGridTextColumn()
    {
        Header = "Color",
        Binding = new Binding("Color")
    };

    columns.Add(color_col);
    if (AttributeVisible == Visibility.Visible)
    {
        columns.Add(new DataGridTextColumn()
        {
            Header = AttributeType,
            Binding = new Binding("Attribute")
        });
    }
    foreach (string s in Items.Select(i => i.Size).Distinct())
    {
        columns.Add(new DataGridTextColumn()
        {
            Header = s,
            Binding = new Binding("Sizes[0].Item2")
            //This works, for binding one Size's Quantity to all of the Columns
            //But I need something that does it for each column like a Hashmap
            //Sizes[s].Item2,
            //or a list Sizes.Where(i => i.Item1 == s).Select(i => i.Item2)
        });
    }
    ColumnCollection = new ObservableCollection<DataGridColumn>(columns);
}

The Model for the row is:该行的模型是:

class StyleGridRow
{
    public string Color
    {
        get;
        set;
    }
    public string Attribute
    {
        get;
        set;
    }

    //The Sizes Property also contains the quantity for the size.
    /*public Hashtable Sizes
    {
        get;
        set;
    }*/

    public List<Tuple<string, int>> Sizes
    {
        get;
        set;
    }


    public StyleGridRow()
    {
        this.Color = "";
        this.Attribute = "";
        this.Sizes = new Hashtable();
    }
    public StyleGridRow(ref string Color, ref string Attribute, ref Hashtable Sizes)
    {
        this.Color = Color;
        this.Attribute = Attribute;
        this.Sizes = Sizes;
    }        
}

I have not yet figured out a way to allow the PropertyPath of the Binding to cooperate.我还没有想出一种方法可以让 Binding 的 PropertyPath 进行协作。

Is there any kind of datatype that will work for this purpose or do I need to change my StyleGridRow to better suit the design?是否有任何类型的数据类型可以用于此目的,或者我是否需要更改 StyleGridRow 以更好地适应设计?

Have you tried changing the array index manually:您是否尝试过手动更改数组索引:

// Add an index to specify the array offset
int index = 0;
// The Distinct() will cause issues finding the correct array offset.
// You may need to use GroupBy() or another mechanism to group the
// column with the size.
foreach (string s in Items.Select(i => i.Size).Distinct())
{
    columns.Add(new DataGridTextColumn()
    {
        Header = s,
        // The array index must exist already. You can put a check for it above if needed.
        Binding = new Binding(string.Format("Sizes[{0}].Item2", index)),
    });
    index++;
}

EDIT: It might be better to use an ObservableCollection for the sizes.编辑:对于尺寸使用 ObservableCollection 可能会更好。 You can either use two arrays or create another class.您可以使用两个数组或创建另一个类。 Ideally, you would use another class and refactor the Distinct() to a higher level so all of the StyleGridRow elements have the same order and length:理想情况下,您将使用另一个类并将 Distinct() 重构到更高级别,以便所有StyleGridRow元素具有相同的顺序和长度:

// implement INPC for notifications, but I won't show it for brevity
public class SizeColumn : INotifyPropertyChanged
{
    public string Header { get; set; }
    public int Count { get; set; }
    public int Index { get; set; }
}

class StyleGridRow
{
    // ...
    public ObservableCollection<SizeColumn> SizeColumns { get; set; }
    // ...
}

// ...
int index = 0;
var sizeColumns = new List<SizeColumn>();
// TODO: Refactor `Select().Distinct()` this so all rows will have same order and length
var sizes = Items.Select(i => i.Size).Distinct().ToList();
foreach (string s in sizeColumns)
{
    // Assuming you are summing the values, and the property name is `Value`
    var count = Items.Where(x => x.Size == s).Sum(i => i.Value);
    sizeColumns.Add(new SizeColumn()
    {
        Header = s,
        Count = count,
        Index = index,
    });
    columns.Add(new DataGridTextColumn()
    {
        Header = s,
        Binding = new Binding(string.Format("SizeColumns[{0}].Count", index)),
    });
    ++index;
}
SizeColumns = new ObservableCollection<SizeColumn>(sizeColumns);
ColumnCollection = new ObservableCollection<DataGridColumn>(columns);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM