以编程方式在WPF中创建网格作为模板

我想以编程方式创建一个带有样式的基本用户控件。 在这种风格中我想添加一个Grid (没问题),但是我不能在这个网格中添加列定义。

我的示例代码是

 ControlTemplate templ = new ControlTemplate(); FrameworkElementFactory mainPanel = new FrameworkElementFactory(typeof(DockPanel)); mainPanel.SetValue(DockPanel.LastChildFillProperty, true); FrameworkElementFactory headerPanel = new FrameworkElementFactory(typeof(StackPanel)); headerPanel.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal); headerPanel.SetValue(DockPanel.DockProperty, Dock.Top); mainPanel.AppendChild(headerPanel); FrameworkElementFactory headerImg = new FrameworkElementFactory(typeof(Image)); headerImg.SetValue(Image.MarginProperty, new Thickness(5)); headerImg.SetValue(Image.HeightProperty, 32d); headerImg.SetBinding(Image.SourceProperty, new Binding("ElementImage") { RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent) }); headerPanel.AppendChild(headerImg); FrameworkElementFactory headerTitle = new FrameworkElementFactory(typeof(TextBlock)); headerTitle.SetValue(TextBlock.FontSizeProperty, 16d); headerTitle.SetValue(TextBlock.VerticalAlignmentProperty, VerticalAlignment.Center); headerTitle.SetBinding(TextBlock.TextProperty, new Binding("Title") { RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent) }); headerPanel.AppendChild(headerTitle); FrameworkElementFactory mainGrid = new FrameworkElementFactory(typeof(Grid)); FrameworkElementFactory c1 = new FrameworkElementFactory(typeof(ColumnDefinition)); c1.SetValue(ColumnDefinition.WidthProperty, new GridLength(1, GridUnitType.Star)); FrameworkElementFactory c2 = new FrameworkElementFactory(typeof(ColumnDefinition)); c2.SetValue(ColumnDefinition.WidthProperty, new GridLength(1, GridUnitType.Auto)); FrameworkElementFactory c3 = new FrameworkElementFactory(typeof(ColumnDefinition)); c3.SetValue(ColumnDefinition.WidthProperty, new GridLength(3, GridUnitType.Star)); FrameworkElementFactory colDefinitions = new FrameworkElementFactory(typeof(ColumnDefinitionCollection)); colDefinitions.AppendChild(c1); colDefinitions.AppendChild(c2); colDefinitions.AppendChild(c3); mainGrid.AppendChild(colDefinitions); mainPanel.AppendChild(mainGrid); FrameworkElementFactory content = new FrameworkElementFactory(typeof(ContentPresenter)); content.SetBinding(ContentPresenter.ContentProperty, new Binding() { RelativeSource = new RelativeSource(RelativeSourceMode.TemplatedParent), Path = new PropertyPath("Content") }); mainGrid.AppendChild(content); templ.VisualTree = mainPanel; Style mainStyle = new Style(); mainStyle.Setters.Add(new Setter(UserControl.TemplateProperty, templ)); this.Style = mainStyle; 

但是,使用ColumnDefinitionCollection类型创建FrameworkElementFactory将引发exception"'ColumnDefinitionCollection' type must derive from FrameworkElement, FrameworkContentElement, or Visual3D."

谁能帮我?

FrameworkElementFactory有一些自定义逻辑,用于处理Grid中的ColumnDefinitions和RowDefinitions。 对于这些值,您可以将它们视为工厂树中的子项,例如:

 FrameworkElementFactory gridFactory = new FrameworkElementFactory(typeof(Grid)); var column1 = new FrameworkElementFactory(typeof(ColumnDefinition)); column1.SetValue(ColumnDefinition.WidthProperty, new GridLength(1, GridUnitType.Auto)); var column2 = new FrameworkElementFactory(typeof(ColumnDefinition)); column2.SetValue(ColumnDefinition.WidthProperty, new GridLength(1, GridUnitType.Star)); gridFactory.AppendChild(column1); gridFactory.AppendChild(column2); 

你可以简单地添加这样的列定义

XAML代码:

      

C#代码:

 ColumnDefinition c = new ColumnDefinition(); c.Width = new GridLength(50, GridUnitType.Pixel); ColumnDefinition c1 = new ColumnDefinition(); c1.Width = new GridLength(100, GridUnitType.Pixel); ColumnDefinition c2 = new ColumnDefinition(); c2.Width = new GridLength(0, GridUnitType.Star); grMain.ColumnDefinitions.Add(c); grMain.ColumnDefinitions.Add(c1); grMain.ColumnDefinitions.Add(c2); 

更多检查在这里

 //create grid var grid = new FrameworkElementFactory(typeof(Grid)); // assign template to grid CellControlTemplate.VisualTree = grid; // define grid's rows var r = new FrameworkElementFactory(typeof(RowDefinition)); grid.AppendChild(r); // define grid's columns var c = new FrameworkElementFactory(typeof(ColumnDefinition)); grid.AppendChild(c); c = new FrameworkElementFactory(typeof(ColumnDefinition)); c.SetValue(ColumnDefinition.WidthProperty, GridLength.Auto); grid.AppendChild(c); c = new FrameworkElementFactory(typeof(ColumnDefinition)); c.SetValue(ColumnDefinition.WidthProperty, GridLength.Auto); grid.AppendChild(c); 

您只需要更改代码的最后部分。 见下文,

原始代码:

  colDefinitions.AppendChild(c1); colDefinitions.AppendChild(c2); colDefinitions.AppendChild(c3); mainGrid.AppendChild(colDefinitions); 

新代码:

  mainGrid.AppendChild(c1); mainGrid.AppendChild(c2); mainGrid.AppendChild(c3);