让我们从场景开始:
我在 UserControl 中有一个 ItemsControl。在这个 ItemsControl 中,我有一个动态创建的 DataTemplate,它是在代码隐藏中创建和添加的。由于似乎没有在代码隐藏中创建 DataTemplate 的好方法,因此我必须以编程方式将 DataTemplate 的 xaml 代码生成为字符串,然后通过 XamlReader 从中创建 DataTemplate 对象:
StringBuilder stringBuilder = new StringBuilder();
XmlWriter xmlWriter = XmlWriter.Create(stringBuilder);
... // use xmlWrite to generate desired xaml
// substring is use to cut out the xml declaration
DataTemplate template = (DataTemplate)XamlReader.Load(stringBuilder.ToString().Substring(39));
myItemsControl.ItemTemplate = template;
生成的 XAML 代码如下所示并且实际使用(项目按预期呈现):
<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Grid HorizontalAlignment="Stretch" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding b0}" Grid.Column="0" />
<TextBox Text="{Binding b1, Converter={StaticResource customConverter}}" HorizontalAlignment="Stretch" Grid.Column="1" LostFocus="TxtAttribute_LostFocus" />
<TextBox Text="{Binding b2, Converter={StaticResource customConverter}}" HorizontalAlignment="Stretch" Grid.Column="2" LostFocus="TxtAttribute_LostFocus" />
<TextBox Text="{Binding b3, Converter={StaticResource customConverter}}" HorizontalAlignment="Stretch" Grid.Column="3" LostFocus="TxtAttribute_LostFocus" IsReadOnly="True" />
</Grid>
如果您想知道:XamlReader 需要 xmlns 属性来呈现控件,否则在访问代码时会出现异常。
我的问题:
现在,虽然项目看起来像预期的那样并且数据被正确绑定,但我的 customConverter 应该重新格式化绑定的数据,也没有正确应用 LostFocus 事件。我没有收到任何错误消息或警告,转换器和事件只是没有被调用。任何人都知道为什么以及如何让它发挥作用?
更新:
我到了必须解决这个问题或尝试不同方法的地步。在我上次的测试中,我尝试直接在 DataTemplate 中添加转换器,但我没有运气。生成的代码现在如下所示:
<DataTemplate xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Conv="clr-namespace:my.Namespace" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<Grid HorizontalAlignment="Stretch" Margin="0,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
<ColumnDefinition Width="80" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Conv:DecimalConverter x:Name="cnvDecimalConverter" />
</Grid.Resources>
<TextBlock Text="{Binding b0}" Grid.Column="0" />
<TextBox Text="{Binding b1, Converter={StaticResource cnvItemsDecimalConverter}}" HorizontalAlignment="Stretch" Grid.Column="1" LostFocus="TxtAttribute_LostFocus" />
<TextBox Text="{Binding b2, Converter={StaticResource cnvItemsDecimalConverter}}" HorizontalAlignment="Stretch" Grid.Column="2" LostFocus="TxtAttribute_LostFocus" />
<TextBox Text="{Binding b3, Converter={StaticResource cnvItemsDecimalConverter}}" HorizontalAlignment="Stretch" Grid.Column="3" LostFocus="TxtAttribute_LostFocus" IsReadOnly="True" />
</Grid>
</DataTemplate>
有任何想法吗?
更新 2:
正如我刚刚发现 XamlReader.Load() 只是无法连接事件。在 Silverlight 论坛中查看此主题
转换器应该可以工作,我想我仍然有某种我没有看到的命名空间问题。我对我的“简单” ItemsControl 方法有点选择,所以我认为是时候寻找另一种方法来满足我的需求了。