[英]Create a grid in WPF as Template programmatically
I want to create a basic user control with a style programmatically. 我想以编程方式创建一个带有样式的基本用户控件。 In this style I want to add a
Grid
(no problem), but I can't add column definitions to this grid. 在这种风格中我想添加一个
Grid
(没问题),但是我不能在这个网格中添加列定义。
My example code is 我的示例代码是
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;
But the creation of FrameworkElementFactory
with type ColumnDefinitionCollection
will throw an exception "'ColumnDefinitionCollection' type must derive from FrameworkElement, FrameworkContentElement, or Visual3D."
但是,使用
ColumnDefinitionCollection
类型创建FrameworkElementFactory
将抛出异常"'ColumnDefinitionCollection' type must derive from FrameworkElement, FrameworkContentElement, or Visual3D."
Who can help me? 谁能帮我?
FrameworkElementFactory has some custom logic for handling the ColumnDefinitions and RowDefinitions in a Grid. FrameworkElementFactory有一些自定义逻辑,用于处理Grid中的ColumnDefinitions和RowDefinitions。 For those values, you treat them like children in the factory tree, for example:
对于这些值,您可以将它们视为工厂树中的子项,例如:
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);
you can simply add column definitions like this 你可以简单地添加这样的列定义
XAML Code: XAML代码:
<Grid.ColumnDefinitions>
<ColumnDefinition Height="50"/>
<ColumnDefinition Height="100"/>
<ColumnDefinition Height="*"/>
</Grid.ColumnDefinitions>
C# Code: 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);
You just need to change the last part of your code. 您只需要更改代码的最后一部分。 See below,
见下文,
Original Code: 原始代码:
colDefinitions.AppendChild(c1);
colDefinitions.AppendChild(c2);
colDefinitions.AppendChild(c3);
mainGrid.AppendChild(colDefinitions);
New Code: 新守则:
mainGrid.AppendChild(c1);
mainGrid.AppendChild(c2);
mainGrid.AppendChild(c3);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.