0

As a learning resource, I want to convert a project that has most of the work done by XAML to be backend code. So, here is the original XAML code I cam trying to convert.

<Page x:Class="EJCSpeechDictionary.ChineseEnglish"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      mc:Ignorable="d" 
      d:DesignHeight="294.667" d:DesignWidth="444"
    Title="ChineseEnglish" Height="294.667" Width="444">
    <Page.Resources>
        <XmlDataProvider x:Key="XmlData"
                   Source="DictionaryData.xml"
                   XPath="WordList/Word"/>
    </Page.Resources>
    <Grid>
        <Grid.DataContext>
            <XmlDataProvider x:Name="XmlData" Source="DictionaryData.xml" XPath="WordList/Word"/>
        </Grid.DataContext>
        <ListBox Name="listBx" ItemsSource="{Binding XPath=/WordList/Word/Chinese}" IsSynchronizedWithCurrentItem="True" HorizontalAlignment="Left" Height="162" Margin="10,10,0,0" VerticalAlignment="Top" Width="151"/>
        <TextBox IsReadOnly="True" Text="{Binding XPath=../English}" Name="spokenWords" DataContext="{Binding ElementName=listBx, Path=SelectedItem}" HorizontalAlignment="Left" Margin="262,127,0,0" VerticalAlignment="Top" Width="171" Height="20"/>
        <Button Content="Speak" Name="speakBtn" HorizontalAlignment="Left" Margin="262,152,0,0" VerticalAlignment="Top" Width="75" Click="speakBtn_Click"/>

    </Grid>
</Page>

So far, I have tried using Observable collection and have yielded a result of the C# programming gods telling me NO! My listbox is completely empty when I run the program. Here is the code from what i've done so far:

    public class Data : INotifyPropertyChanged
    {
        private string chinese;
        private string pinyin;
        private string english;
        private const string filePath = @"https://onedrive.live.com/redir?resid=20c5e1cad5eac97f!22900&authkey=!AAjCLv_ozEqrdAY&ithint=file%2cxml";

        public string Chinese
        {
            get 
            { return this.chinese; }
            set
            {
                if (this.chinese != value)
                {
                    this.chinese = value;
                    this.NotifyPropertyChanged("Chinese");
                }
            }
        }
        public string Pinyin
        {
            get { return this.pinyin; }
            set
            {
                if (this.pinyin != value)
                {
                    this.pinyin = value;
                    this.NotifyPropertyChanged("Pinyin");
                }
            }
        }

        public string English
        {
            get { return this.english; }
            set
            {
                if (this.english != value)
                {
                    this.english = value;
                    this.NotifyPropertyChanged("English");
                }
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propName)
        {
            if (this.PropertyChanged != null)
                this.PropertyChanged(this, new PropertyChangedEventArgs(propName));
        }

        public void deserializeXML()
        {
            if (File.Exists(filePath))
            {
                XmlSerializer deserializer = new XmlSerializer(typeof(Data));
                TextReader reader = new StreamReader(filePath);
                object obj = deserializer.Deserialize(reader);
                Data XmlData = (Data)obj;
                reader.Close();
            }
        }
    }
}


    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private ObservableCollection<Data> calledData = new ObservableCollection<Data>();

        public MainWindow()
        {
            InitializeComponent();

            Data data = new Data();
            data.deserializeXML();
            listBox.ItemsSource = data.Chinese;
        }
    }
}

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--This is a generated XML File-->
<WordList>
  <Word>
    <English>able</English>
    <Pinyin>Néng</Pinyin>
    <Chinese>能</Chinese>
  </Word>
  <Word>
    <English>aboard</English>
    <Pinyin>Chuánshàng</Pinyin>
    <Chinese>船上</Chinese>
  </Word>
  <Word>
    <English>about</English>
    <Pinyin>Dàyuē</Pinyin>
    <Chinese>大约</Chinese>
  </Word>
  <Word>
    <English>above</English>
    <Pinyin>Yǐshàng</Pinyin>
    <Chinese>以上</Chinese>
  </Word>
  <Word>
    <English>accept</English>
    <Pinyin>Jiēshòu</Pinyin>
    <Chinese>接受</Chinese>
  </Word>
  </WordList>

So, as it stands right now, I am at a loss for what I am doing wrong with the code. Any pointers (ha! I crack myself up with puns) in the right direction would be greatly appreciated.

Jesse Glover
  • 325
  • 3
  • 14

1 Answers1

1

First thing, In the method deserializeXML in Data class you are reading the data from XML and creating a new Data object called XmlData and it is scope is only within that method meaning it is lost, even though you are reading the data it is discarded.

Second, your xml root element is a list (WordList) containing list of Word, and each Word is what you've defined in Data. You also need to define Word List as a class WordList then, create a XmlSerializer(typeof(WordList)); I used the xsd.exe to convert your sample .xml to .xsd (schema) and then to c# class. Refer here on how to convert xml to c# class

using System.Xml.Serialization;

// 
// This source code was auto-generated by xsd, Version=4.0.30319.1.
// 

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class WordList {

    private WordListWord[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("Word", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public WordListWord[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
public partial class WordListWord {

    private string englishField;

    private string pinyinField;

    private string chineseField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string English {
        get {
            return this.englishField;
        }
        set {
            this.englishField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string Pinyin {
        get {
            return this.pinyinField;
        }
        set {
            this.pinyinField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string Chinese {
        get {
            return this.chineseField;
        }
        set {
            this.chineseField = value;
        }
    }
}

The Data class you've defined is similar to the WordListWord!

Finally you can set your datacontext to WordList.Items.ToList() or an ObservableCollection(WordList.Items)

Community
  • 1
  • 1
Ash
  • 657
  • 9
  • 16