如何为FrameworkElementFactory生成自定义列(typeof(Datagrid))?

时间:2017-10-02 09:12:34

标签: c# wpf datagrid

我有DataGrid,它必须在RowDetails中有childGrid但我不知道如何为子网格创建列。
目前我有自动生成列的子网格,我不需要:

private static bool CopyWork(TextBox textBox)
{
    try
    {
        var match = Regex.Match(textBox.Text, @"^коп раб");
        if (match.Success)
        {
            var copyWorkWindow = new Window()
            {
                Topmost = true,
                WindowStartupLocation = WindowStartupLocation.CenterScreen,
                Title = "Копирование документов",
                SizeToContent = SizeToContent.WidthAndHeight
            };
            var documents = new ObservableCollection<CopyWorkDocument>();
            var dataGrid = new DataGrid()
            {
                ItemsSource = documents,
                AutoGenerateColumns = false
            };

            var generateColumn = new Func<string, string, object[], FrameworkElementFactory>((header, bindingItem, items) =>
            {
                var column = new FrameworkElementFactory(typeof(DataGridTemplateColumn));
                column.SetValue(DataGridTemplateColumn.HeaderProperty, header);

                var binding1 = new Binding(bindingItem)
                {
                    Mode = BindingMode.TwoWay
                };

                var elementTextBlock = new FrameworkElementFactory(typeof(TextBlock));
                elementTextBlock.SetValue(TextBlock.TextProperty, binding1);
                var cellTemplate = new DataTemplate
                {
                    VisualTree = elementTextBlock
                };
                column.SetValue(DataGridTemplateColumn.CellTemplateProperty, cellTemplate);

                if (items != null)
                {
                    var elementComboBox = new FrameworkElementFactory(typeof(ComboBox));
                    elementComboBox.SetValue(ComboBox.BackgroundProperty, Brushes.White);
                    elementComboBox.SetValue(ComboBox.ItemsSourceProperty, items);
                    elementComboBox.SetValue(ComboBox.SelectedItemProperty, binding1);
                    var cellEditingTemplate = new DataTemplate
                    {
                        VisualTree = elementComboBox
                    };
                    column.SetValue(DataGridTemplateColumn.CellEditingTemplateProperty, cellEditingTemplate);
                }

                return column;
            });
            dataGrid.Columns.Add(new DataGridTextColumn() { Header = "Название документа", Binding = new Binding("Name") });
            dataGrid.Columns.Add(new DataGridTextColumn() { Header = "Количество копий", Binding = new Binding("Documentcount") });

            var rowDetailsTemplate = new DataTemplate();
            var pagesGrid = new FrameworkElementFactory(typeof(DataGrid));
            //pagesGrid.SetValue(DataGrid.AutoGenerateColumnsProperty, false);
            pagesGrid.SetValue(DataGrid.ItemsSourceProperty, new Binding("Pages"));
            rowDetailsTemplate.VisualTree = pagesGrid;
            dataGrid.RowDetailsTemplate = rowDetailsTemplate;

            copyWorkWindow.Content = dataGrid;
            copyWorkWindow.ShowDialog();
            var sB = new StringBuilder();
            foreach (var document in documents)
            {
                sB.Append(document).Append(Environment.NewLine);
            }
            if (sB.Length > 0)
            {
                textBox.Text = sB.ToString();
            }
        }
        return match.Success;
    }
    catch (Exception ex)
    {
        ex.LogAndShow();
        return false;
    }
}  

下面有columnGenerator 对象类:

private class CopyWorkDocument
{
    public string Name { get; set; }
    public int Documentcount { get; set; } = 1;
    public List<CopyPage> Pages { get; set; } = new List<CopyPage> { new CopyPage() };

    public override string ToString()
    {
        var sB = new StringBuilder().Append(Name);
        foreach (var page in Pages)
        {
            sB.Append(Environment.NewLine).Append(Documentcount).Append("шт (").Append(page).Append(")");
        }
        return sB.ToString();
    }

    public class CopyPage
    {
        public int Pagecount { get; set; } = 1;
        public string Pageformat { get; set; } = "A4";
        public string Worktype { get; set; } = "печать";
        public string Printtype { get; set; } = "односторонняя";
        public bool IsColored { get; set; } = false;

        public static string[] Worktypes { get => new string[] { "печать", "копирование", "сканирование", "брошюровка", "твердый переплет" }; }
        public static string[] Printtypes { get => new string[] { "односторонняя", "двусторонняя" }; }
        public static string[] Formats { get => new string[] { "A4", "A3", "A2", "A1" }; }

        public override string ToString()
        {
            var sB = new StringBuilder().Append(Pagecount).Append(" ").Append(Pageformat);
            if (IsColored)
            {
                sB.Append(" цвет");
            }
            return sB.ToString();
        }
    }
}  

colum generator的示例:

DataGrid.Columns.Add(generateColumn("ColumnName", "ColumnBinding", "ColumnItemsHelper"[]));

首先我为DataGrid(Conrol)做了这个生成器,但后来我为FrameworkElementFactory重做它(由于StackOverflow代码限制帖子,这个无用的细节被添加)

1 个答案:

答案 0 :(得分:1)

如MSDN所述,使用FrameworkElementFactory类是一种不常用的编程方式来创建模板:https://msdn.microsoft.com/en-us/library/system.windows.frameworkelementfactory(v=vs.110).aspx

您可以改为使用System.Windows.Markup.XamlReader.Parse方法:

StringBuilder sb = new StringBuilder();
sb.Append("<DataTemplate xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\" xmlns:x =\"http://schemas.microsoft.com/winfx/2006/xaml\">");
sb.Append("<DataGrid ItemsSource=\"{Binding Pages}\" AutoGenerateColumns=\"False\">");
sb.Append("<DataGrid.Columns>");
//append for each column:
sb.Append("<DataGridTextColumn Binding=\"{Binding Name}\" Header=\"Name\" />");
sb.Append("</DataGrid.Columns>");
sb.Append("</DataGrid>");
sb.Append("</DataTemplate>");
dataGrid.RowDetailsTemplate = XamlReader.Parse(sb.ToString()) as DataTemplate;