Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

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."

Who can help me?

like image 724
wickie79 Avatar asked Dec 23 '10 08:12

wickie79


People also ask

How do I add a grid in WPF?

First Method: By typing XAML CodeRowDefinitions property and a ColumnDefinition Element for each column inside the Grid. ColumnDefinitions property. By default, GridLines are invisible. For showing the GridLines, set the ShowGridLines property of the Grid to True.

How do I create a dynamic grid in WPF?

Wpf application Dynamic grid is implemented as user control that contains DataGrid control bound to observable collection of collections of cell view models. In this implementation collection of cells is recreated each time if grid width or grid height is changed, and it leads to some application pauses.

How do you add rows and columns to a WPF grid programmatically?

RowDefinitions. Add(gridRow3); Once rows and columns are added to Grid, you can add any contents to Grid cells by using SetRow and SetColumn methods. SetRow and SetColumn methods take first parameter as the control name and second parameter as row number and column number respectively.


2 Answers

FrameworkElementFactory has some custom logic for handling the ColumnDefinitions and RowDefinitions in a Grid. 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);
like image 198
Pavan Avatar answered Sep 24 '22 17:09

Pavan


you can simply add column definitions like this

XAML Code:

<Grid.ColumnDefinitions>
<ColumnDefinition Height="50"/>
<ColumnDefinition Height="100"/>
<ColumnDefinition Height="*"/>
</Grid.ColumnDefinitions>

C# Code:

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

for more check here

like image 37
biju Avatar answered Sep 22 '22 17:09

biju