Créer une grid dans WPF en tant que modèle par programme

Je veux créer un contrôle utilisateur de base avec un style par programme. Dans ce style, je souhaite append une Grid (pas de problème), mais je ne peux pas append de définitions de colonne à cette grid.

Mon exemple de code est

 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; 

Mais la création de FrameworkElementFactory avec le type ColumnDefinitionCollection va ColumnDefinitionCollection une exception "'ColumnDefinitionCollection' type must derive from FrameworkElement, FrameworkContentElement, or Visual3D."

Qui peut m’aider?

FrameworkElementFactory dispose d’une logique personnalisée pour gérer les colonnes ColumnDefinitions et RowDefinitions dans une grid. Pour ces valeurs, vous les traitez comme des enfants dans l’arborescence de l’usine, par exemple:

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

vous pouvez simplement append des définitions de colonne comme celle-ci

Code XAML:

      

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

pour plus de vérifier ici

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

Il vous suffit de changer la dernière partie de votre code. Voir ci-dessous,

Code d’origine:

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

Nouveau code:

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