Привязка данных между файлом XML и графическим интерфейсом - PullRequest
0 голосов
/ 03 февраля 2010

У меня проблема с моим маленьким приложением, которое концептуально очень просто.У меня есть XML-файл, который по существу просто отображает строки в строки.


Предупреждение о длинных пояснениях


Пример файла будет выглядеть примерно так:

<Candies>
  <Sees>Box1</Sees>
  <Hersheys>Box2</Hersheys>
  <Godiva>Box3</Godiva>
</Candies>

Хотя я мог бы использовать другую схему, например:

<Candies>
  <Candy>
    <Name>Sees</Name>
    <Location>Box1</Location>
  </Candy>
</Candies>

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

В коде я загружаю содержимое своего XML-файла в XDocument с помощью LINQ.У меня также определена переменная List, потому что это то, к чему я привязываю свой графический интерфейс.CandyLocation выглядит следующим образом:

public class CandyLocation
{
  public string Brand { get; set; }
  public string Location { get; set; }
}

И мой простой графический интерфейс выглядит так:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="Auto" Width="Auto">

    <Page.Resources>
        <DataTemplate x:Key="CandyTemplate">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>
                <TextBox Grid.Column="0" Text="{Binding Brand}" Margin="3"></TextBox>
                <ComboBox Grid.Column="1" SelectedValue="{Binding Location}" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Page}}, Path=DataContext.LocationNames}" Text="{Binding Location, Mode=TwoWay}" Margin="3"></ComboBox>
            </Grid>
        </DataTemplate>
    </Page.Resources>

    <DockPanel>
        <Button DockPanel.Dock="Bottom" Margin="3" Command="{Binding SaveCandiesCommand}">Apply Changes</Button>
        <Button DockPanel.Dock="Bottom" Margin="3" Command="{Binding AddNewCandyCommand}">Add Candy</Button>
        <ListBox DockPanel.Dock="Top" ItemsSource="{Binding CandyLocations}" ItemTemplate="{StaticResource CandyTemplate}" />
    </DockPanel>
</Page>

Итак, обзор таков:

Приложение загружается, а затем использует LINQзагрузить файл XML.Когда отображается GUI, он вызывает «GetCandyLocations», который пересекает данные XML и заполняет объект List содержимым файла XML.При начальной загрузке XML графический интерфейс отображается правильно (т. Е. Марки конфет и их местоположение отображаются правильно), но на этом история успеха заканчивается.


Если я начну с пустого файла XML и добавлюя делаю это, добавляя новый XElement в мой корень XDocument.Затем я вызываю OnPropertyChanged ("CandyLocations"), чтобы обновить GUI.Начальное значение для Местоположения - "", таким образом, пользователь должен выбрать правильное местоположение из выпадающего списка.Проблема в том, что я не могу понять, как правильно получить привязку к данным выбора, чтобы я мог обновить значение XElement.Из-за этого, когда я сохраняю расположения конфет, все заканчивается пустым значением местоположения.Кроме того, каждый раз, когда пользователь нажимает кнопку «Добавить конфету», все ранее выбранные комбинированные списки местоположений отключаются.

В итоге:

  1. Как следует обрабатывать изменения выбора в графическом интерфейсе?Я использую MVVM для этого приложения, поэтому я избегаю использовать событие SelectionChanged ComboBox.
  2. Есть ли способ привязки данных напрямую из GUI к XDocument?Я еще не пробовал, но было бы лучше избегать использования нескольких источников данных (например, XDocument для сериализации и List для визуализации GUI).Возможно, я смогу заставить получателя вернуть результат запроса LINQ и связать его с преобразователем значения ???
  3. Как бы вы изменили мою реализацию, если бы написали это приложение?Я все еще изучаю MVVM и WPF, поэтому любой совет был бы очень полезен.

Спасибо!

1 Ответ

1 голос
/ 03 февраля 2010

В вашем ComboBox похоже, что вы можете получить конфликт между свойствами SelectedValue и Text.Текст обычно используется только с IsEditable = "True".Попробуйте использовать только SelectedItem:

<ComboBox SelectedItem="{Binding Location}" ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Page}}, Path=DataContext.LocationNames}" ></ComboBox>

Если вы хотите использовать XDocument напрямую в качестве источника данных, вы можете использовать его (при условии, что XDocument предоставляется от виртуальной машины в виде AvailableLocations):

<ComboBox ItemsSource="{Binding Path=AvailableLocations.Root.Elements}" SelectedValue="{Binding Location}"
          SelectedValuePath="Value" DockPanel.Dock="Top" DisplayMemberPath="Value"/>

Если вы предпочитаете отображать названия компаний, просто измените DisplayMemberPath на «Имя».

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

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