wpf 如何以编程方式创建包含内容的数据模板?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8427972/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I create a datatemplate with content programmatically?
提问by Corpsekicker
I want to do the following at runtime in code:
我想在运行时在代码中执行以下操作:
<DataTemplate x:Key="lightGreenRectangle">
<Rectangle Fill="LightGreen"/>
</DataTemplate>
So far I've got:
到目前为止,我有:
public DataTemplate GetColouredRectangleInDataTemplate(Color colour)
{
DataTemplate dataTemplate = new dataTemplate();
return dataTemplate;
}
Help? I know this isn't the most elegant way of styling a control, but the component I want to specify a colour for has a property called "PointTemplate" of type DataTemplate.
帮助?我知道这不是设置控件样式的最优雅的方式,但是我想为其指定颜色的组件有一个名为“PointTemplate”的 DataTemplate 类型的属性。
回答by FunnyItWorkedLastTime
If for whatever reason you need to create a DataTemplate
programmatically you would do:
如果出于某种原因需要以DataTemplate
编程方式创建一个,则可以执行以下操作:
XAML:
XAML:
<Grid x:Name="myGrid">
<ContentControl ContentTemplate="{DynamicResource lightGreenRectangle}" />
</Grid>
Somewhere in your code:
在您的代码中的某处:
public static DataTemplate CreateRectangleDataTemplate()
{
var rectangleFactory = new FrameworkElementFactory(typeof(Rectangle));
rectangleFactory.SetValue(Shape.FillProperty, new SolidColorBrush(System.Windows.Media.Colors.LightGreen));
return new DataTemplate
{
VisualTree = rectangleFactory,
};
}
public static void AddRectangleTemplateToResources(FrameworkElement element)
{
element.Resources.Add("lightGreenRectangle", CreateRectangleDataTemplate());
}
Then you just need to add the DataTemplate
to a ResourceDictionary
so it can be used. For example, in the code behind:
然后你只需要将DataTemplate
加到 a 中ResourceDictionary
就可以使用了。例如,在后面的代码中:
public MainWindow()
{
InitializeComponent();
AddRectangleTemplateToResources(myGrid);
}
Hope this helps!
希望这可以帮助!
回答by Paulo Zemek
Using the following helper class:
使用以下帮助类:
/// <summary>
/// Class that helps the creation of control and data templates by using delegates.
/// </summary>
public static class TemplateGenerator
{
private sealed class _TemplateGeneratorControl:
ContentControl
{
internal static readonly DependencyProperty FactoryProperty = DependencyProperty.Register("Factory", typeof(Func<object>), typeof(_TemplateGeneratorControl), new PropertyMetadata(null, _FactoryChanged));
private static void _FactoryChanged(DependencyObject instance, DependencyPropertyChangedEventArgs args)
{
var control = (_TemplateGeneratorControl)instance;
var factory = (Func<object>)args.NewValue;
control.Content = factory();
}
}
/// <summary>
/// Creates a data-template that uses the given delegate to create new instances.
/// </summary>
public static DataTemplate CreateDataTemplate(Func<object> factory)
{
if (factory == null)
throw new ArgumentNullException("factory");
var frameworkElementFactory = new FrameworkElementFactory(typeof(_TemplateGeneratorControl));
frameworkElementFactory.SetValue(_TemplateGeneratorControl.FactoryProperty, factory);
var dataTemplate = new DataTemplate(typeof(DependencyObject));
dataTemplate.VisualTree = frameworkElementFactory;
return dataTemplate;
}
/// <summary>
/// Creates a control-template that uses the given delegate to create new instances.
/// </summary>
public static ControlTemplate CreateControlTemplate(Type controlType, Func<object> factory)
{
if (controlType == null)
throw new ArgumentNullException("controlType");
if (factory == null)
throw new ArgumentNullException("factory");
var frameworkElementFactory = new FrameworkElementFactory(typeof(_TemplateGeneratorControl));
frameworkElementFactory.SetValue(_TemplateGeneratorControl.FactoryProperty, factory);
var controlTemplate = new ControlTemplate(controlType);
controlTemplate.VisualTree = frameworkElementFactory;
return controlTemplate;
}
}
You can create a data-template like this:
您可以像这样创建数据模板:
DataTemplate template =
TemplateGenerator.CreateDataTemplate
(
() =>
{
var result = new TextBox()
result.SetBinding(TextBox.TextProperty, "BindingPathHere");
return result;
}
);
You are free to use any code to create the control as you will do if you were creating the control directly, without any data-template. For more info, see this tip in code project: http://www.codeproject.com/Tips/808808/Create-Data-and-Control-Templates-using-Delegates
您可以随意使用任何代码来创建控件,就像直接创建控件一样,无需任何数据模板。有关详细信息,请参阅代码项目中的此提示:http: //www.codeproject.com/Tips/808808/Create-Data-and-Control-Templates-using-Delegates