Использование привязки к XML в Silverlight - PullRequest
0 голосов
/ 14 февраля 2011

У меня сейчас проблемы с привязкой XML к графическому интерфейсу в приложении Silverlight.Особенно с TwoWay-Binding.

Как мы знаем, это действительно легко сделать в клиентском приложении Windows с использованием WPF.Там вы можете просто сделать что-то вроде:

XML:

<person>
  <firstname>Test</firstname>
  <surname>Test</surname>
  <email>testc@testc.com</email>
</person>

и страницу XAML с просмотром таблицы для редактирования (связывание с использованием XLinq или XPath):

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="3*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="30" />
        <RowDefinition Height="30" />
        <RowDefinition Height="30" />
        <RowDefinition Height="221*" />
    </Grid.RowDefinitions>
    <TextBlock Grid.Column="0" Grid.Row="0" Text="First name:" />
    <TextBox Grid.Column="1" Grid.Row="0" Text="{Binding Path=Element[firstname].Value, Mode=TwoWay}" />
    <TextBlock Grid.Column="0" Grid.Row="1" Text="Surname:" />
    <TextBox Grid.Column="1" Grid.Row="1" Text="{Binding Path=Element[surname].Value, Mode=TwoWay}" />
    <TextBlock Grid.Column="0" Grid.Row="2" Text="EMail:" />
    <TextBox Grid.Column="1" Grid.Row="2" Text="{Binding Path=Element[email].Value, Mode=TwoWay}" />
</Grid>

Из-за режима TwoWay-режима пользователь записывает напрямую в XML.

Однако в Silverlight нет возможности связывать, как в примере выше.Но Microsoft добавила XPathEvaluate-Method () в Silverlight 4.

Поэтому я пытался связать полный XDocument с каждым TextBox и использовать конвертер вместе с ConverterParameter для передачи выражения XPath и его оценки.

<Grid x:Name="LayoutRoot">
    <TextBlock Text="{Binding Path=Data, Converter={StaticResource TestKonverter}, ConverterParameter=//firstname, Mode=TwoWay}" FontSize="20" />
</Grid>

и ...

public class XMLConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var __doc = (XDocument)value;
        var __xpath = (IEnumerable)__doc.XPathEvaluate(parameter.ToString());

        return (__xpath.Cast<XElement>().FirstOrDefault());
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        //getting the attached XDocument again as __doc ?!
        var __xpath = (IEnumerable)__doc.XPathEvaluate(parameter.ToString());

        (__xpath.Cast<XElement>().FirstOrDefault()).Value = value.ToString();

        return value;
    }
}

Чтобы получить своего рода двухстороннее связывание, я подумал об использовании XPath-выражения, чтобы получить правильный узел и записать в него новое значение.Проблема в том, что в ConvertBack-Method () я не вижу способа, как получить XDocument.Есть ли способ получить XDocument через заданные параметры в ConvertBack, не делая его где-то статичным?

Ответы [ 2 ]

2 голосов
/ 22 марта 2011

Спасибо за ваш ответ.

Около двух недель назад я решил эту проблему, просто создав новый класс с именем XTextBox.Я просто наследую от TextBox и создаю два DependencyProperties с типами XElement и string в новом классе.

В моем XAML я могу использовать привязку, как я это делал раньше, и передать полный XElement и XPath, чтобы найти правильноеузел для моего элемента управления.

<custom:XTextBox Data="{Binding Path=XValues, Mode=TwoWay}" XPath="//Measurements/Headline/Fontsize" />

Помимо двух свойств DependencyProperties, я использую обычное событие TextChanged для обновления значения в XElement с помощью XPath.

Это полностью решает привязку TwoWay, потому чтоМне никогда не нужно создавать новый XElement и копировать все вокруг.Я также реализовал XComboBox, XRadioButton и XCheckBox, чего достаточно в моем случае.

0 голосов
/ 21 марта 2011

цитата из вопроса на форуме silverlight -

"Вы можете создать класс для хранения ваших данных и реализовать INotifyPropertyChanged, а затем прочитать или написать свой xml в коде.

Если формат вашегоxml еще не определен, вы можете использовать DataContractSerializer.

написать пример xml:

  YourDataClassType data = new YourDataClassType();  
  MemoryStream ms = new MemoryStream();
  DataContractSerializer ds = new DataContractSerializer(typeof(YourDataClassType));
  ds.WriteObject(ms, data);
  ms.Flush();
  ms.Seek(0, SeekOrigin.Begin);
  StreamReader sr = new StreamReader(ms);
  string xml = sr.ReadToEnd();
  sr.Close();
  ms.Close();

прочитать пример xml:

MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
sw.Write(xml);
sw.Flush();

ms.Seek(0, SeekOrigin.Begin);

DataContractSerializer ds = new DataContractSerializer(typeof(YourDataClassType));
YourDataClassType data = ds.ReadObject(ms) as YourDataClassType;
sw.Close();
ms.Close();

где YourDataClassType - ваш класскоторый отражает данные. Таким образом, вам не нужно разбирать xml самостоятельно. "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...