如何为FrameworkElementFactory

如何为FrameworkElementFactory

本文介绍了如何为FrameworkElementFactory(typeof(Datagrid))生成自定义列?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have DataGrid which must have childGrid in RowDetails but i dont know how to create columns for child grid.
At the moment i have child grid with Autogenerated columns that i dont need:

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.
对象类别:

There is columnGenerator below.
Object class:

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

列生成器示例:

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

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

First i did this generator for DataGrid (Conrol), but then i rework it for FrameworkElementFactory (This useless details added because of StackOverflow codelimitation post)

推荐答案

如MSDN上所述,使用 FrameworkElementFactory 类是通过编程方式创建模板的不建议使用的方法: https://msdn.microsoft.com/zh-CN/library/system.windows.frameworkelementfactory(v=vs.110).aspx .

As stated on MSDN, using the FrameworkElementFactory class is a deprecated way to programmatically create templates: 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;

这篇关于如何为FrameworkElementFactory(typeof(Datagrid))生成自定义列?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 02:59