EventBinding в коде позади сгенерированного DataTemplate - PullRequest
0 голосов
/ 27 марта 2009

Давайте начнем со сценария:

У меня есть ItemsControl внутри UserControl. В этом ItemsControl у меня есть динамически созданный DataTemplate, который создается и добавляется в коде позади. Поскольку не представляется хорошим способом создания DataTemplate в коде, мне пришлось программно сгенерировать код xaml для моего DataTemplate в строку, а затем создать объект DataTemplate из него через XamlReader:

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>

В случае, если вам интересно: атрибут xmlns необходим XamlReader для визуализации элемента управления, иначе вы получите исключение при достижении кода.

Моя проблема:

теперь, пока элементы выглядят как ожидаемые и данные правильно связаны, ни мой customConverter, который должен переформатировать связанные данные, ни событие LostFocus не применяются правильно. Я не получаю никаких сообщений об ошибках или предупреждений, конвертер и событие просто не вызывают. Кто-нибудь знает, почему и как я могу заставить это работать?

Обновление:

Я пришел к тому, что мне нужно решить эту проблему или попробовать другой подход. В моих последних тестах я пытался добавить конвертер непосредственно в шаблон данных, но мне не повезло. Сгенерированный код теперь выглядит так:

<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, поэтому я думаю, что пришло время искать другой метод для удовлетворения моих потребностей.

1 Ответ

0 голосов
/ 03 апреля 2009

Просто чтобы прояснить ситуацию: невозможно генерировать динамические шаблоны данных с событиями через генерацию строки xaml и извлечь из нее элемент управления. Единственный вариант для анализа кода xaml с событиями - через Application.LoadComponent, для работы которого требуется URI.

Я использовал вложенные ItemControls для создания своего "динамического" поведения.

...