【发布时间】:2014-07-02 23:39:43
【问题描述】:
我正在试验一些代码,我需要将编程创建的控件与 XAML 中定义的控件混合在一起。
有人可以解释为什么当我绑定到 Elements View 属性时,该属性的“get”被调用了两次,而当绑定到 Template 属性时它只被调用一次(如预期的那样)。
绑定到视图时的示例输出:
StringElement
StringElement
BoolElement
BoolElement
StringElement
StringElement
绑定到模板时的示例输出:
StringElement
BoolElement
StringElement
--
<Window x:Class="BindView.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" WindowStartupLocation="CenterScreen">
<ItemsControl ItemsSource="{Binding Elements}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding View}" />
</DataTemplate>
<!--<DataTemplate>
<ContentPresenter ContentTemplate="{Binding Template}" />
</DataTemplate>-->
</ItemsControl.ItemTemplate>
</ItemsControl>
public abstract class Element
{
public DataTemplate Template
{
get
{
Console.WriteLine(GetType().Name);
return OnGetTemplate();
}
}
public abstract DataTemplate OnGetTemplate();
public UIElement View
{
get
{
Console.WriteLine(GetType().Name);
return OnGetView();
}
}
public abstract UIElement OnGetView();
protected DataTemplate CreateTemplate(Type viewType)
{
var xaml = string.Format("<DataTemplate><{0} /></DataTemplate>", viewType.Name);
var context = new ParserContext();
context.XamlTypeMapper = new XamlTypeMapper(new string[0]);
context.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
context.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
return (DataTemplate)XamlReader.Parse(xaml, context);
}
}
public class StringElement : Element
{
public override DataTemplate OnGetTemplate() { return CreateTemplate(typeof(TextBox)); }
public override UIElement OnGetView() { return new TextBox(); }
}
public class BoolElement : Element
{
public override DataTemplate OnGetTemplate() { return CreateTemplate(typeof(CheckBox)); }
public override UIElement OnGetView() { return new CheckBox(); }
}
public partial class MainWindow : Window
{
public List<Element> Elements { get; private set; }
public MainWindow()
{
Elements = new List<Element>() { new StringElement(), new BoolElement(), new StringElement() };
DataContext = this;
InitializeComponent();
}
}
【问题讨论】:
标签: c# wpf templates binding contentpresenter