How to read xml in combobox in datagrid?

I am trying to read xml file in dataset and bind dataset to datagrid

XML file:

<NewDataSet>
    <Communications>
        <ModelNumber>1</ModelNumber>
        <ParamName>BaudRate</ParamName>
        <ParamValues>
            <ParamValue>9600</ParamValue>
            <ParamValue>19200</ParamValue>
            <ParamValue>115200</ParamValue>
        </ParamValues>
        <DefaultValue>19200</DefaultValue>
        <MaxValue></MaxValue>
        <MinValue></MinValue>
    </Communications>
    <Communications>
        <ModelNumber>1</ModelNumber>
        <ParamName>Parity</ParamName>
        <ParamValues>
            <ParamValue>None</ParamValue>
            <ParamValue>Odd</ParamValue>
            <ParamValue>Even</ParamValue>
        </ParamValues>
        <DefaultValue>None</DefaultValue>
        <MaxValue></MaxValue>
        <MinValue></MinValue>
    </Communications>
        <Communications>
        <ModelNumber>1</ModelNumber>
        <ParamName>StopBit</ParamName>
        <ParamValues>
           <ParamValue>1</ParamValue>
           <ParamValue>2</ParamValue>
        </ParamValues>
        <DefaultValue>1</DefaultValue>
        <MaxValue></MaxValue>
        <MinValue></MinValue>
    </Communications>
    <Communications>
        <ModelNumber>1</ModelNumber>
        <ParamName>DataBit</ParamName>
        <ParamValues>
           <ParamValue>7</ParamValue>
           <ParamValue>8</ParamValue>
        </ParamValues>
        <DefaultValue>8</DefaultValue>
        <MaxValue></MaxValue>
        <MinValue></MinValue>
   </Communications>
   <Communications>
        <ModelNumber>1</ModelNumber>
        <ParamName>SlaveAddress</ParamName>
        <ParamValues>
            <ParamValue>1</ParamValue>
        </ParamValues>
        <DefaultValue>1</DefaultValue>
        <MaxValue>247</MaxValue>
        <MinValue>1</MinValue>
   </Communications>
</NewDataSet>

      

Read xml in dataset:

    public ObservableCollection<Communication> GetCommunications()
    {
        DataSet ds = new DataSet();
        ds.ReadXml("Communications.xml");
        ObservableCollection<Communication> communications = new ObservableCollection<Communication>();
        foreach (DataRow communicationRow in ds.Tables["Communications"].Rows)
        {
            var c = new Communication((ushort)Convert.ToInt16(communicationRow["ModelNumber"]), communicationRow["ParamName"].ToString(),
                    ds.Tables["ParamValue"].Rows[0][0].ToString(), communicationRow["DefaultValue"].ToString(), communicationRow["MaxValue"].ToString(),
                    communicationRow["MinValue"].ToString());
            foreach (DataRow dr in ds.Tables["ParamValue"].Rows)
            {
                c.ParamValues.Add(dr[0].ToString());
            }
            communications.Add(c);
        }
        return communications;
    }

      

Related Datagrid:

    <DataGridTemplateColumn Header="ParamValues">                                              
       <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                 <ComboBox ItemsSource="{Binding ParamValues}" SelectedItem="{Binding DefaultValue}" />
            </DataTemplate>                                                           
       </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

      

But the above code fails with the error that each combobox column ParamValues

has everything ParamValue

for each table Communications

Image details , could you please tell me how to fix this? Thanks in advance!

+3


source to share


2 answers


Replace DataSet

with XDocument

:



public ObservableCollection<Communication> GetCommunications()
{
    ObservableCollection<Communication> communications = new ObservableCollection<Communication>();
    XDocument doc = XDocument.Load("Communications.xml");
    foreach (XElement communicationRow in doc.Root.Elements("Communications"))
    {
        var c = new Communication((ushort)Convert.ToInt16(communicationRow.Element("ModelNumber").Value), communicationRow.Element("ParamName").Value,
                communicationRow.Element("DefaultValue").Value, communicationRow.Element("DefaultValue").Value, communicationRow.Element("MaxValue").Value,
                communicationRow.Element("MinValue").Value);

        foreach (XElement paramValue in communicationRow.Element("ParamValues").Elements())
        {
            c.ParamValues.Add(paramValue.Value);
        }

        communications.Add(c);
    }

    return communications;
}

      

+3


source


Try following code



using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            DataTable dt = new DataTable("Communications");

            string[] columnNames = doc.Descendants("ParamName").Select(x => (string)x).Distinct().ToArray();

            dt.Columns.Add("ModelNumber", typeof(string));
            foreach (string colName in columnNames)
            {
                dt.Columns.Add(colName, typeof(string));
            }

            var models = doc.Descendants("Communications").GroupBy(x => (string)x.Element("ModelNumber")).ToList();

            foreach(var model in models)
            {
                var orderedModel = model.Select(x => new { 
                    paramCount = x.Descendants("ParamValue").Count(), 
                    parmName = (string)x.Element("ParamName"),
                    parms = x.Descendants("ParamValue").Select(y => (string)y).ToList()
                }).OrderByDescending(x => x.paramCount).ToList();

                for (int parm = 0; parm < orderedModel.FirstOrDefault().paramCount; parm++)
                {
                    DataRow newRow = dt.Rows.Add();
                    newRow["ModelNumber"] = model.Key;
                    foreach(var col in orderedModel)
                    {
                        if (col.paramCount > parm)
                        {
                            newRow[col.parmName] = col.parms[parm];
                        }
                    }


                }
            }
        }
    }
}

      

0


source







All Articles