XML-привязка данных в WPF - PullRequest
       3

XML-привязка данных в WPF

1 голос
/ 02 августа 2010

Я пытаюсь написать приложение, которое декодирует некоторые неподписанные длинные значения. Формат каждого значения представлен в XML как:

<Project Name="Project1">
 <Message Name="a">
  <BitField high="31" low="28">
   <value>0001</value>
   <value>1010</value>
  </Bitfield>
  <BitField high="27" low="17">
   <value>000111101</value>
  </BitField>
  <BitField high="16" low="0">100h</BitField>
 </Message>
</Project>

Теперь значения проекта отображаются в выпадающем списке. Когда пользователь выбирает значение в поле со списком, типы сообщений должны отображаться в списке. Затем, когда пользователь выбирает тип сообщения в списке, должны отображаться битовые поля и значения, которые они могут содержать. Теперь, когда пользователь выбирает значение для каждого битового поля, окончательное значение двойного слова должно отображаться в текстовом поле.

Я сталкивался с примерами, чтобы проанализировать полный XML, но не относящийся к выбору. Нужны ваши парни, помогите здесь.

Еще одна вещь заключается в том, что пользователь может ввести значение dword в текстовое поле. Теперь, как я могу сделать это обратное связывание декодирования меча в текстовом поле и отобразить соответствующее сообщение + значение, используя интерфейс, описанный выше?

ОБНОВЛЕНИЕ: Теперь я установил связь между полем со списком, в котором отображаются значения проекта, и списком, в котором отображается сообщение. Следующее, что мне нужно сделать, это когда пользователь выбирает сообщение в списке, битовые поля должны отображаться в виде строк с «high», «low», «value / @ name» (здесь не показано), а затем значение (связанное со значением / @ name) в виде столбцов. Значение / @ name должно отображаться как выпадающий список. Я уверен, что могу сделать это в dataGrid, но я использую .net 3.5, поэтому ищу альтернативу здесь. Кроме того, текстовый блок значения должен быть редактируемым, если узлы отсутствуют в xml. Наконец я получил, чтобы упаковать записи через столбец «значение» в DWORD. Могу ли я сделать это в XAML без сетки данных? Какая альтернатива сетке данных для .Net 3.5?

Ответы [ 3 ]

2 голосов
/ 06 августа 2010

У вас есть две разные проблемы - проблема с разбором XML и проблема с преобразованием.

Чтобы привязка работала, вам нужно проанализировать XML в класс, который представляет его значения. Что касается проблемы преобразования, я указываю вам на концепцию TypeConverters , которые довольно просты в использовании. Что касается вопроса синтаксического анализа XML, я хочу выделить LINQ-to-XML, который, я думаю, является коленями для пчел. Несколько его строк могут воссоздать даже самые сложные объектные графы из источника XML. Для вашего примера Project / Message / BitField я частично реализовал решение, которое даст вам шаблон.

Обратите внимание на метод «LoadFromXml». При этом используется выражение linq-to-xml, которое заполняет ваш граф объектов. Единственное, что этот запрос меняет в вашем XML-источнике, это то, что он ожидает, что узлы коллекции (т.е. или) будут окружены узлами коллекции (т.е.)

   public class Project
    {
        public string Name { get; set; }
        public List<Message> MessageCollection = new List<Message>();

        public void LoadFromXml(string xmlString)
        {
            // From System.Xml.Linq
            XDocument xDocument = XDocument.Parse(xmlString);

            // The following assumes your XML is well formed, is not missing attributes and has no type conversion problems. In
            // other words, there is (almost) zero error checking.
            if (xDocument.Document != null)
            {
                XElement projectElement = xDocument.Element("Project");

                if (projectElement != null)
                {
                    Name = projectElement.Attribute("Name") == null ? "Untitled Project" : projectElement.Attribute("Name").Value;

                    MessageCollection = new List<Message>
                        (from message in xDocument.Element("Project").Elements("Messages")
                         select new Message()
                                {
                                    Name = message.Attribute("Name").Value,
                                    BitfieldCollection = new List<BitField>
                                        (from bitField in message.Elements("Bitfields")
                                            select new BitField() {High = int.Parse(bitField.Attribute("High").Value), Low = int.Parse(bitField.Attribute("Low").Value)})
                                }
                        );
                }
            }
        }
    }

    public class Message
    {
        public string Name { get; set; }
        public List<BitField> BitfieldCollection = new List<BitField>();
    }

    public class BitField
    {
        public int High { get; set; }
        public int Low { get; set; }
        public List<string> ValueCollection = new List<string>();
    }
1 голос
/ 08 августа 2010

Это можно сделать с помощью привязки данных и XMLReaders. Сначала создайте свой пользовательский интерфейс, желательно внутри родительской панели (таким образом, мы можем установить текст данных панели, и все дочерние элементы управления будут наследовать этот контекст).

Далее создайте пользовательский класс (назовем его Project). Убедитесь, что каждое поле в этом классе обновляет PropertyDependencyInfo, иначе привязка данных не будет работать.

Затем привяжите свойства Content или Itemssource элементов управления вашего пользовательского интерфейса к полям вашего класса Project.

Затем создайте код для чтения XML, используя класс XMLReader или класс XPathReader. Затем, когда вы получили доступ к данным из файла, настройте поля нового объекта Project так, чтобы они соответствовали данным, которые вы хотите прочитать.

После создания экземпляра объекта Project и правильного присвоения ему значений из XML установите родительскую Panel из свойства DataContext пользовательского интерфейса в свой объект Project. Все поля пользовательского интерфейса должны быть обновлены.

Если вам необходимо загрузить другой файл, все, что вам нужно сделать, это повторить чтение XML с другим именем файла.

Что касается вашего обновления: строки и столбцы могут управляться одним из следующих способов:

Элемент управления Grid / UniformGrid, чьи дочерние элементы RowDefinition и ColumnDefinition создаются и изменяются во время выполнения для управления увеличением и уменьшением количества полей

или: набор StackPanels, по одному на каждый столбец (так как количество столбцов никогда не изменяется). Вы можете напрямую добавить комбинированные списки в StackPanel для своего столбца value / @ name или изменить ItemTemplate StackPanel (если он есть, я не могу найти машину для проверки в данный момент).

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

1 голос
/ 07 августа 2010

Вам определенно нужно иметь в виду разделение модели и вида и внешнее представление модели.В зависимости от того, насколько велик ваш фактический XML и какой вид API вам удобнее, вы можете использовать несколько совершенно разных способов чтения XML и превращения его в реальные объекты, которые затем будут служить моделью для вашего пользовательского интерфейса.Просто важно помнить об этом разделении.

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

Таким образом, при условии, что все изменчиво, самый быстрый способ получитьЗначения из тегов могут быть просто для создания XPathDocumen и выбора XPath, который вы можете сохранить в виде строки или даже в конфигурации.Например, это даст вам все теги Value (теперь они называются узлами)

//Project/Message/BitField/Value

, и, поскольку объекты для узлов имеют указатели Parent, вы можете собирать все значения, которые совместно используют Parent (в список или массив), а затем сделатьобъект для родителя (BitField), сохраните его и убедитесь, что у него есть указатель Parent из XmlNode.После того, как у вас есть все объекты BitField, вы можете так же отсканировать их, чтобы сгруппировать их по родителям (Message) и снова получить Project-s.Это всего лишь один из способов, вы можете использовать более короткий XPath, чтобы начать собирать данные из BitField и самостоятельно захватывать их дочерние элементы.

Вы также можете создать несколько простых классов, которые дословно представляют ваши теги XML (по одному элементу данных для каждогополе, один класс для каждого тега) и поместите атрибуты для XmlSerialization на затем.Это займет несколько попыток, чтобы получить правильные имена, но одна у вас есть, вы сможете просто "десериализовать" весь файл с помощью вызова функции и получить массив массивов или массивов :-) из .NET.

Если ваши файлы очень, очень большие, то вам, вероятно, придется использовать XmlTextReader и сканировать файл сверху вниз - точная обратная выборка XPath (XmlTextReader - самый легкий способ анализа, не создающий лишних тоновобъект, но вы должны повторить его в несколько взглядов и всегда "ходить" от родителя к ребенку, поскольку он односторонний).

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

Да, и еслиу вас есть какое-либо влияние на формат XML, попробуйте заставить ppl всегда помещать это значение в тег значения, даже если он всего один.Файл XML будет немного длиннее, но ваша обработка будет упрощена.

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