C# · 12月 29, 2021

c# – 以编程方式在WPF中创建一个网格作为模板

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

我的示例代码是

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,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的创建将抛出异常“”ColumnDeFinitionCollection“类型必须从FrameworkElement,FrameworkContentElement或Visual3D派生.

谁能帮我?

解决方法 FrameworkElementFactory有一些自定义逻辑来处理Grid中的ColumnDeFinitions和RowDeFinitions.对于这些价值观,您可以像工厂树中的孩子一样对待他们,例如: FrameworkElementFactory gridFactory = new FrameworkElementFactory(typeof(Grid));var column1 = new FrameworkElementFactory(typeof(ColumnDeFinition)); column1.SetValue(ColumnDeFinition.WidthProperty,GridUnitType.Auto)); var column2 = new FrameworkElementFactory(typeof(ColumnDeFinition)); column2.SetValue(ColumnDeFinition.WidthProperty,GridUnitType.Star));gridFactory.AppendChild(column1);gridFactory.AppendChild(column2);