Привязка XML в Silverlight без именных классов - PullRequest
3 голосов
/ 04 декабря 2008

Допустим, у меня есть простой кусок XML: -

<root>
   <item forename="Fred" surname="Flintstone" />
   <item forename="Barney" surname="Rubble" />
</root>

Получив этот XML в Silverlight, я хотел бы связать его с XAML этого аналога: -

<ListBox x:Name="ItemList" Style="{StaticResource Items}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">           
                <TextBox Text="{Binding Forename}" />
                <TextBox Text="{Binding Surname}" />  
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox> 

Теперь я могу достаточно просто связать с LINQ to XML и номинальным классом: -

public class Person {
     public string Forename {get; set;} 
     public string Surname {get; set;}
}

Можно ли это сделать без этого класса?

Другими словами, связь между кодом Silverlight и входным XML ограничивается только XAML, другой исходный код не зависит от набора атрибутов элемента item.

Редактировать : предлагается использовать XSD, но в конечном итоге это то же самое. XSD-> Генерируемый класс.

Редактировать : анонимный класс не работает, Silverlight не может их связать.

Редактировать : Это должен быть двусторонний процесс, пользователь должен иметь возможность редактировать значения, и эти значения в конечном итоге окажутся в XML. (Изменен оригинальный TextBlock на TextBox в примере выше.)

Ответы [ 4 ]

3 голосов
/ 04 декабря 2008

Вы можете сделать это с помощью IValueConverter. Вот простой:

public class XAttributeConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        var xml = value as XElement;
        var name = parameter as string;
        return xml.Attribute(name).Value;
    }
}

Затем в вашем Xaml вы можете ссылаться на преобразователь типов и передавать имя атрибута в качестве параметра:

<ListBox x:Name="ItemList">
    <ListBox.Resources>
        <local:XAttributeConverter x:Name="xcvt" />
    </ListBox.Resources>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding Converter={StaticResource xcvt}, ConverterParameter=forename}" />
                <TextBlock Text="{Binding Converter={StaticResource xcvt}, ConverterParameter=surname}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Это когда вы привязываетесь к XML, загруженному в XElement:

XElement xml = XElement.Parse("<root><item forename='Fred' surname='Flintstone' /><item forename='Barney' surname='Rubble' /></root>");

ItemList.ItemsSource = xml.Descendants("item");

Не очень элегантный синтаксис привязки, но он работает и проще, чем сопоставление с классами.

2 голосов
/ 05 июня 2010

См. Связывание с анонимными типами в Silverlight для получения информации.

0 голосов
/ 04 декабря 2008

Не могли бы вы сделать что-то похожее на то, что предлагает Брайант с запросом, который использует анонимный класс?

т.е:.

var data = from c in xml.Descendants("item")
                       select new  { Forename = c.Attribute("forename").Value, 
                                     Surname = c.Attribute("surname").Value };
ItemList.ItemsSource = data

Я думаю, что это должно сработать, но я не где-нибудь, чтобы проверить это. Если этого не произойдет, кто-нибудь, дайте мне знать, почему, потому что теперь я заинтересован.

0 голосов
/ 04 декабря 2008

Насколько мне известно, в Silverlight Binding отсутствуют свойства XPath, найденные в WPF, поэтому нет хорошего способа привязки напрямую к XML. Когда я столкнулся с этой проблемой, я использовал xsd.exe для схемы, чтобы сгенерировать мои классы, а затем использовать сериализацию Xml для их заполнения. Это не идеально, но, по крайней мере, я сам не пишу и не поддерживаю классы и отображения.

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