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