Форум программистов, компьютерный форум, киберфорум
Наши страницы
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
 
NewEd
4 / 4 / 2
Регистрация: 11.10.2007
Сообщений: 52
#1

MVVM. Загрузить данные из xml в DateGrid? - C# WPF

17.10.2015, 14:09. Просмотров 602. Ответов 5
Метки нет (Все метки)

На форме View.xaml, запускаемой при старте приложения, расположен DateGrid и кнопка «Load xml to DataGrid».
Есть файл FileSample.xml в котором записаны данные для этой DateGrid. Проект в приложенном архиве DateGrid - question.rar.

1) Как правильно, с соблюдением паттерна MVVM, считать данные из FileSample.xml и прибайндить их к DateGrid:
A) при старте приложения?
Б) по нажатию на кнопке?

FileSample.xml
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="utf-8"?>
<FAIL>
  <DATA>
    <MYTABLE>
      <TABLEROW VAL_1="1" VAL_2="Строка 1"/>
      <TABLEROW VAL_1="2" VAL_2="Строка 2"/>
      <TABLEROW VAL_1="3" VAL_2="Строка 3"/>
    </MYTABLE>
  </DATA>
</FAIL>


View.xalm
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<Window   
            x:Class="DataGridQuestion.MainWindow"        
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    
            xmlns:local="clr-namespace:DataGridQuestion.ViewModel"
    
            WindowStartupLocation="CenterScreen"
            WindowState="Normal"
            Title="DataGridQuestion" Height="200" Width="300"
    >
 
    <Window.DataContext>
        <local:ViewModel/>
    </Window.DataContext>
 
    <Grid  VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ShowGridLines="False">
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
 
        <!--MVVM. Как прописать байндинг данных из xml к DataGrid?-->
        <DataGrid x:Name="dgrMiddle"  Grid.Row="0" Grid.Column="0"  AutoGenerateColumns="False"
                                    ItemsSource="{Binding Path=MyTable, Mode=TwoWay}"
                                    >
            <!--MVVM. Как прописать байндинг данных из xml к DataGrid в DataGridTextColumn?-->
            <DataGrid.Columns>
                <DataGridTextColumn Header="VAL_1" Binding="{Binding Path = VAL_1, Mode=TwoWay}"/>
                <DataGridTextColumn Header="VAL_2" Binding="{Binding Path = VAL_2, Mode=TwoWay}"/>
            </DataGrid.Columns>
        </DataGrid>
 
        <!--MVVM. Как прописать байндинг данных из xml к DataGrid при клике на кнопке?-->
        <Button Grid.Row="0" Grid.Column="1" Height="30" VerticalAlignment="Top" Click="Button_Click">Load xml to DataGrid</Button>
    </Grid>
</Window>


Модель - ObjectTables.cs
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
using System;
 
namespace DataGridQuestion.Models
{
    public class MyTable
    {
        public Int64 VAL_1 { get; set; }
        public string VAL_2 { get; set; }
    }
}


ViewModel.cs
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
using System;
using System.IO;
using System.ComponentModel;
using DataGridQuestion.Models;
 
namespace DataGridQuestion.ViewModel
{
    public class ViewModel : INotifyPropertyChanged
    {
        private DataGridQuestion.Models.MyTable _MyTable;
 
        public event PropertyChangedEventHandler PropertyChanged;
        protected void OnPropertyChanged(string propName)
        {
            PropertyChangedEventHandler temp = PropertyChanged;
            if (temp != null)
            {
                temp(this, new PropertyChangedEventArgs(propName));
            }
        }
        public ViewModel()
        {
 
            string xmlUrl = Directory.GetCurrentDirectory();
            xmlUrl = Directory.GetParent(xmlUrl).ToString();
            xmlUrl = Directory.GetParent(xmlUrl).ToString() + "\\FileSample.xml";
 
 
            _MyTable = XMLParsers.ParseMyTable(xmlUrl);
        }
    }
}

2) XMLParsers.cs – Правильный ли такой подход к парсингу xml-файла и как устранить ошибку, которая возникает на строке
C#
1
var myelement = xdoc.Element("DATA").Element("MYTABLE").Element("TABLEROW");
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Xml.Linq;
 
namespace DataGridQuestion.Models
{
    public class XMLParsers
    {
        public static MyTable ParseMyTable(String path)
        {
            var mytbl = new MyTable();
            XDocument xdoc = XDocument.Load(path);
 
//Почему на этой строке выдаёт ошибку?
            var myelement = xdoc.Element("DATA").Element("MYTABLE").Element("TABLEROW");
            //--------------------------------------
            mytbl.VAL_1 = Convert.ToInt64(myelement.Element("VAL_1").Value);
            mytbl.VAL_2 = myelement.Element("VAL_2").Value;
            return mytbl;
        }
    }
}


Спасибо.
1
Вложения
Тип файла: rar DataGrid - question.rar (203.2 Кб, 1 просмотров)
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
17.10.2015, 14:09
Я подобрал для вас темы с готовыми решениями и ответами на вопрос MVVM. Загрузить данные из xml в DateGrid? (C# WPF):

MVVM. Загрузить данные из xml в DatePicker?
На форме View.xaml, запускаемой при старте приложения, расположен DatePicker....

Загрузить данные в классы из файла формата xml
Всем привет. Пытаюсь загрузить данные из файлика в соответствующие классы...

Редактирование XML-datagrid в WPF и паттерн MVVM
Добрый день, извините сразу, перелазил 720 страниц различной инфы не нашел,...

MVVM. Как подключить данные к DataGridComboBoxColumn?
На форме View.xaml, запускаемой при старте приложения, расположен DateGrid,...

Обновлять коллекцию, не перезаписывая данные, а добавляя новые в ежедневнике MVVM
Здравствуйте! Пишу сейчас небольшой ежедневник. Есть класс который добавляет...

Как правильно передать данные из View во ViewModel чтобы не нарушить шаблон MVVM
Здравствуйте. Вопрос такой есть View в него загружается html страница из...

5
NewEd
4 / 4 / 2
Регистрация: 11.10.2007
Сообщений: 52
18.10.2015, 22:51  [ТС] #2
Для загрузки данных из xml при старте программы придумал нижеописанный вариант, но не уверен, что он канонически правильный.
Пожалуйста, подскажите, что следует сделать более правильно?
XMLParsers.cs не используется (пока не нашёл решения как правильно перенести часть кода в него).
Весь код во ViewModel.cs Остальное не менялось - см. выше.
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Collections.ObjectModel; //Для ObservableCollection
 
using DataGridQuestion.Models;
 
namespace DataGridQuestion.ViewModel
{
    public class ViewModel
    {
        public ObservableCollection<MyTable> MiddleTable {get; set;}
        public ViewModel()
        {
            //указываю путь к файлу с xml данными FileSample.xml
            string xmlUrl = Directory.GetCurrentDirectory();
            xmlUrl = Directory.GetParent(xmlUrl).ToString();
            xmlUrl = Directory.GetParent(xmlUrl).ToString() + "\\FileSample.xml";
            
            //загружаю данные из файла в документ
            XDocument xdoc = XDocument.Load(xmlUrl);
            
            //считываю только те поля и их значения, которые нужны для таблицы
            var importXML = (from MYTABLE in xdoc.Root.Elements("DATA").Elements("MYTABLE").Elements("TABLEROW")
                                  select new
                                  {
                                      VAL_1 = Convert.ToInt64(MYTABLE.Attribute("VAL_1").Value),
                                      VAL_2 = MYTABLE.Attribute("VAL_2").Value,
                                  }).ToList();
 
            //т.к. в качестве источника данных для DataGrid можно использовать только коллекции, создаю ObservableCollection
            MiddleTable = new ObservableCollection<MyTable>();
 
            //переписываю все значения из importXML в ObservableCollection
            foreach (var ev in importXML)
            {
                MiddleTable.Add (new MyTable { VAL_1 = ev.VAL_1, VAL_2 = ev.VAL_2});
            }
        }
    }
}

В View.xalm записываю байндинг таблицы так
Кликните здесь для просмотра всего текста
XML
1
2
3
4
5
6
7
8
        <DataGrid x:Name="dgrMiddle"  Grid.Row="0" Grid.Column="0"  AutoGenerateColumns="False"
                                    ItemsSource="{Binding Path=MiddleTable, Mode=TwoWay}"
                                    >
            <DataGrid.Columns>
                <DataGridTextColumn Header="VAL_1" Binding="{Binding Path = VAL_1, Mode=TwoWay}"/>
                <DataGridTextColumn Header="VAL_2" Binding="{Binding Path = VAL_2, Mode=TwoWay}"/>
            </DataGrid.Columns>
        </DataGrid>
0
kenny69
burning1ife
1371 / 1198 / 282
Регистрация: 21.09.2008
Сообщений: 3,356
Записей в блоге: 9
19.10.2015, 00:24 #3
Если нужно только для отображения данных из xml, то можно делать напрямую во View исключая ViewModel
http://www.c-sharpcorner.com/UploadF...-wpf-datagrid/

Добавлено через 45 секунд
Для Xml используется XPath
XML
1
Text="{Binding  XPath=@Director}"
0
NewEd
4 / 4 / 2
Регистрация: 11.10.2007
Сообщений: 52
19.10.2015, 08:34  [ТС] #4
Спасибо за информацию. Такой вариант для моего случая не подходит, т.к. нужно будет выполнять операции в DataGrid и требуется именно MVVM.
0
NewEd
4 / 4 / 2
Регистрация: 11.10.2007
Сообщений: 52
19.10.2015, 22:22  [ТС] #5
По нажатию на кнопку данные в DataGrid загружаются, но не отображаются.
Если пишу public class ViewModel : INotifyPropertyChanged, возникает сообщение об ошибке: 'ViewModel' does not implement interface member 'INotifyPropertyChanged.PropertyChanged'
Как исправить?
Для загрузки данных в DataGrid по нажатию кнопки прописал:
В View.xaml добавил байндинг на кнопку:
Кликните здесь для просмотра всего текста
XML
1
<Button Grid.Row="0" Grid.Column="1" Height="30" VerticalAlignment="Top" Command="{Binding Path=ClickCommand}">Load xml to DataGrid</Button>


В ViewModel.cs добавил ClickCommand = new RelayCommand(arg => ClickMethod()); и загрузку значений из xml перенёс в private void ClickMethod()
Кликните здесь для просмотра всего текста
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
using System;
using System.IO;
using System.Linq;
using System.Xml.Linq;
using System.Collections.ObjectModel; //Для ObservableCollection
using System.Windows.Input;//для комманд
using System.ComponentModel;//для комманд
 
 
using DataGridQuestion.Models;
 
namespace DataGridQuestion.ViewModel
{
    public class ViewModel 
    {
 
        public ICommand ClickCommand { get; set; }
        public ObservableCollection<MyTable> MiddleTable {get; set;}
 
         public ViewModel()//конструктор
        {
 
          ClickCommand = new RelayCommand(arg => ClickMethod());
 
            #region загрузка DataGrid при старте
            //////указываю путь к файлу с xml данными FileSample.xml
            ////string xmlUrl = Directory.GetCurrentDirectory();
            ////    xmlUrl = Directory.GetParent(xmlUrl).ToString();
            ////    xmlUrl = Directory.GetParent(xmlUrl).ToString() + "\\FileSample.xml";
 
            ////    //загружаю данные из файла в документ
            ////    XDocument xdoc = XDocument.Load(xmlUrl);
 
            ////    //считываю только те поля и их значения, которые нужны для таблицы
            ////    var importXML = (from MYTABLE in xdoc.Root.Elements("DATA").Elements("MYTABLE").Elements("TABLEROW")
            ////                          select new
            ////                          {
            ////                              VAL_1 = Convert.ToInt64(MYTABLE.Attribute("VAL_1").Value),
            ////                              VAL_2 = MYTABLE.Attribute("VAL_2").Value,
            ////                          }).ToList();
 
            ////    //т.к. в качестве источника данных для DataGrid можно использовать только коллекции, создаю ObservableCollection
            ////    MiddleTable = new ObservableCollection<MyTable>();
 
            ////    //переписываю все значения из importXML в ObservableCollection
            ////    foreach (var ev in importXML)
            ////    {
            ////        MiddleTable.Add (new MyTable { VAL_1 = ev.VAL_1, VAL_2 = ev.VAL_2});
            ////    }
            #endregion загрузка DataGrid при старте
        }
 
        private void ClickMethod() //загрузка данных в DataGrid нажатием на кнопку
        {
            //указываю путь к файлу с xml данными FileSample.xml
            string xmlUrl = Directory.GetCurrentDirectory();
            xmlUrl = Directory.GetParent(xmlUrl).ToString();
            xmlUrl = Directory.GetParent(xmlUrl).ToString() + "\\FileSample.xml";
 
            //загружаю данные из файла в документ
            XDocument xdoc = XDocument.Load(xmlUrl);
 
            //считываю только те поля и их значения, которые нужны для таблицы
            var importXML = (from MYTABLE in xdoc.Root.Elements("DATA").Elements("MYTABLE").Elements("TABLEROW")
                             select new
                             {
                                 VAL_1 = Convert.ToInt64(MYTABLE.Attribute("VAL_1").Value),
                                 VAL_2 = MYTABLE.Attribute("VAL_2").Value,
                             }).ToList();
 
            //т.к. в качестве источника данных для DataGrid можно использовать только коллекции, создаю ObservableCollection
            MiddleTable = new ObservableCollection<MyTable>();
 
            //переписываю все значения из importXML в ObservableCollection
            foreach (var ev in importXML)
            {
                MiddleTable.Add(new MyTable { VAL_1 = ev.VAL_1, VAL_2 = ev.VAL_2 });
            }
        }
    }
}


Остальное не менялось.
0
Вложения
Тип файла: rar DataGrid - question.rar (82.1 Кб, 1 просмотров)
NewEd
4 / 4 / 2
Регистрация: 11.10.2007
Сообщений: 52
20.10.2015, 23:31  [ТС] #6
Лучший ответ Сообщение было отмечено Ev_Hyper как решение

Решение

Благодаря помощи экспертов получены ответы на все вопросы.
Работающий проект в приложенном архиве.
Надеюсь окажется полезным.
3
Вложения
Тип файла: rar ComplexDataGrid.rar (74.4 Кб, 50 просмотров)
20.10.2015, 23:31
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.10.2015, 23:31
Привет! Вот еще темы с решениями:

Загрузить xml файл на форму в виде таблицы
Здраствуйте! Помогите пожалуйста! Совсем запутался. Перелопатил кучу всего, но...

Загрузить XML документ из строки или потока в памяти
Доброго времени суток уважаемые! Помогите пожалуйста решить следующую...

Загрузить данные в ListBox исходя из выбора в Combobox
Загружаю данные из xml, из &lt;Realms&gt;, этот пункт содержит разные значения...

Как загрузить данные на ftp через прокси
Здравствуйте друзья. Как можно загрузить данные на ftp через прокси? Файлы...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru