0

让我们从场景开始:

我在 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 方法有点选择,所以我认为是时候寻找另一种方法来满足我的需求了。

4

1 回答 1

0

只是为了澄清情况:不可能通过生成 xaml 字符串来生成带有事件的动态 DataTemplates 并从中提取控件。使用事件解析 xaml 代码的唯一选择是通过 Application.LoadComponent ,它需要一个 URI 才能工作。

我最终使用嵌套的 ItemControls 来创建我的“动态”行为。

于 2009-04-03T09:49:11.673 回答