Custom Model as Generic TypeArgument in XAML

Viewed 26

I have made a small class, which inherits from DataGrid and takes in classes that derive from a specific interface:

    public class RecordDataGrid<T> : DataGrid where T : IRecord
    {
        public RecordDataGrid()
        {
            this.AutoGenerateColumns = false;
            this.CanUserAddRows = false;
            this.CanUserDeleteRows = false;
            this.CanUserResizeRows = false;
            this.IsReadOnly = true;
            this.SelectionMode = DataGridSelectionMode.Single;
            this.Margin = new System.Windows.Thickness(0, 10, 0, 0);

            var propertyInfos = typeof(T).GetProperties();

            var list = new Dictionary<PropertyInfo, DataGridColumnAttribute>();

            foreach (var propertyInfo in propertyInfos)
            {
                var customAttributes = propertyInfo.GetCustomAttributes(true);
                foreach (var customAttr in customAttributes)
                {
                    if (customAttr != null && customAttr is DataGridColumnAttribute)
                    {
                        list.Add(propertyInfo, (DataGridColumnAttribute)customAttr);
                    }
                }
            }

            var ordered = (from entry in list orderby entry.Value.OrderIndex ascending select entry).ToDictionary(e => e.Key, e => e.Value);

            foreach (var kvp in ordered)
            {
                var propertyInfo = kvp.Key;
                var dgcAttr = kvp.Value;

                var column = new DataGridTextColumn();
                column.Header = dgcAttr.DisplayName;
                column.Binding = new Binding(propertyInfo.Name);
                column.Binding.StringFormat = dgcAttr.StringFormat ?? null;
                column.Width = dgcAttr.ColumnWidthType == DataGridColumnAttribute.ColumnWidthTypes.Auto ? new DataGridLength(10, DataGridLengthUnitType.Auto) : new DataGridLength(10, DataGridLengthUnitType.Star);
                this.Columns.Add(column);
            }
        }
    }

It is very rough at the moment, just testing a few things out. The goal is to make my life easier by letting the DataGrid fill the Columns by itself, based on a custom Attribute:

    public class DataGridColumnAttribute : Attribute
    {
        public string DisplayName { get; private set; }
        public string StringFormat { get; private set; }
        public ColumnWidthTypes ColumnWidthType { get; private set; }
        public int OrderIndex { get; private set; }

        public DataGridColumnAttribute(string displayName, int orderIndex, string stringFormat = null, ColumnWidthTypes columnWidthType = ColumnWidthTypes.Auto)
        {
            DisplayName = displayName;
            StringFormat = stringFormat;
            OrderIndex = OrderIndex;
            ColumnWidthType = columnWidthType;
        }

        public enum ColumnWidthTypes
        {
            Auto,
            Fill
        }
    }

Later on, as far as I am concerned, I should be able to use it in xaml like this:
Namespaces:

xmlns:model="clr-namespace:NickX.KswErp.Model.Classes;assembly=NickX.KswErp.Model"
xmlns:ctrl="clr-namespace:NickX.KswErp.ClientApplication.UI.Controls"

Control:

<ctrl:RecordDataGrid x:Name="_gridTransactions" x:TypeArguments="model:TransactionRecord" />

But I get following compilation error:

Only a master tag can specify the "x: TypeArguments" attribute.
(Roughly translated by google translation)

Maybe my approach is completely wrong tho. Should I do it completle in code behind. Or are there better approaches? Please let me know!

1 Answers

Conveniently I just found a thread in a german forum, which answeres my exact question. So people questioning the same in the future:

It is not possible. Easiest thing to do at this point is making a specific class for each model, which again derives from your generic class.

In my case:

    public class TransactionDataGrid : RecordDataGrid<TransactionRecord>
    {
    }

Doesen't seem like a nice solution to me, and probably isn't the best way to do it. But it works.

Related