Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Отслеживание изменений в DataGrid / 25 сообщений из 88, страница 1 из 4
06.11.2018, 13:19
    #39728489
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
DataGrid, как я понял, предназначен для работы с БД и работает транзакциями. Поэтому не очень подходит для редактирования небольших списочных свойств. В инете много разных способов приспособления DataGrid для этих целей, но все они какие-то "корявые".
Поэтому и хотел поинтересоваться, более красивым логичным решением.
Приведу пример и объясню, что мне в нём не нравится.

Класс для элементов списка
Код: 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.
  public  class FieldTwoProperty : OnPropertyChangedClass
    {
        private string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; OnPropertyChanged(); }
        }

        private string _value;

        public string Value
        {
            get { return _value; }
            set { _value = value; OnPropertyChanged(); }
        }

        public override bool Equals(object obj)
        {
            var property = obj as FieldTwoProperty;
            return property != null &&
                   _name == property._name &&
                   _value == property._value;
        }

        public override int GetHashCode()
        {
            var hashCode = 179903332;
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(_name);
            hashCode = hashCode * -1521134295 + EqualityComparer<string>.Default.GetHashCode(_value);
            return hashCode;
        }
    }

Модель
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
    public class Model
    {
        List<FieldTwoProperty> _listField;
        public Model()
        {
            _listField = new List<FieldTwoProperty>()
            {
                new FieldTwoProperty(){Name="Телефон",Value= "+0 (123) 456-78-90"},
                new FieldTwoProperty(){Name="Адрес",Value= "Новые Васюки"}
            };
        }
        public IEnumerable<FieldTwoProperty> GetFields() => _listField.ConvertAll(field => new FieldTwoProperty() {Name=field.Name, Value=field.Value });
        public void SetFields(IEnumerable<FieldTwoProperty> value) => _listField = value?.ToList();
        public bool IsEqualsField(IEnumerable<FieldTwoProperty> value)
        {
            if (_listField == null && value == null) return true;
            if (_listField == null || value == null || _listField.Count != value.Count()) return false;
            return value
                .Select((field, ind) => new { Field = field, Index = ind })
                .FirstOrDefault(fieldInd => !fieldInd.Field.Equals(_listField[fieldInd.Index]))
                == null;
        }
    }

Модель представления
Код: 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.
 public   class ViewModel : OnPropertyChangedClass
    {
        private List<FieldTwoProperty> _listFields;

        public List<FieldTwoProperty> ListFields
        {
            get { return _listFields; }
            set { _listFields = value; OnPropertyChanged(); }
        }

        private Model model;

        public ViewModel()
        {
            model = new Model();
            ListFields = model.GetFields().ToList();
        }

        private ICommand _saveComm;
        public ICommand SaveComm => _saveComm ?? (_saveComm = new RelayCommand(OnSave));
        private void OnSave(object value)
        {
            model.SetFields(value as List<FieldTwoProperty>);
            ListFields = model.GetFields().ToList();
        }

        public bool IsNotModified => model.IsEqualsField(_listFields);
        public bool IsModified => !IsNotModified;

        public void Changed() => OnPropertyChanged("IsNotModified IsModified");
    }

Окно
Код: 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.
<Window x:Class="ChangedSourceInDatagrid.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ChangedSourceInDatagrid"
        mc:Ignorable="d" SizeToContent="Height"
        Title="MainWindow" Width="300">
    <d:Window.DataContext>
        <local:ViewModel>
            <local:ViewModel.ListFields>
                <local:FieldTwoProperty Name="Поле 1" Value="Значение 1"/>
                <local:FieldTwoProperty Name="Поле 2" Value="Значение 2"/>
            </local:ViewModel.ListFields>
        </local:ViewModel>
    </d:Window.DataContext>
    <local:ContextHolder>
        <local:ContextHolder.Commands>
            <local:CommandBinding RoutedCommand="{x:Static ApplicationCommands.Save}"
                                  RelayCommand="{Binding SaveComm}"/>
        </local:ContextHolder.Commands>
        <StackPanel>
            <DataGrid x:Name="DG"  Margin="5" ItemsSource="{Binding ListFields, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" ColumnWidth="*" 
                      SelectedCellsChanged="DG_SelectedCellsChanged"
                      LostFocus="DG_LostFocus"/>
            <Button Margin="5" HorizontalAlignment="Center" IsEnabled="{Binding IsModified}" 
                    Command="{x:Static ApplicationCommands.Save}"
                    CommandParameter="{Binding ListFields}">Сохранить</Button>
        </StackPanel>
    </local:ContextHolder>
</Window>

Code Behind
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
    public partial class MainWindow : Window
    {
        private ViewModel viewModel=new ViewModel();
        public MainWindow()
        {
            InitializeComponent();
            DataContext = viewModel;
        }

        private void DG_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
        {
            viewModel.Changed();
        }
        private void DG_LostFocus(object sender, RoutedEventArgs e)
        {
            viewModel.Changed();
        }
    }


Набор классов для работы с командами не прикладываю, он идентичен предоставленному Романом в http://www.sql.ru/forum/1304673/pravilnoe-razmeshhenie-funkcionala-i-privyazki-komand

Теперь что мне не нравится.
1) Использование обработчиков событий для отслеживания изменений в DataGrid. Вызов методов VM из CB.
2) Отсутствие у DataGrid события извещения о немедленном изменений значений в ячейке. В данном пример, это приводит к тому, что кнопка не активна до тех пор пока не выйдешь из первой изменённой ячейки. Если изменяешь только одну и надо сразу сохранить изменения, то так не получится. Т.е. более удобным здесь было бы событие аналогичное TextBox.TextChanged
3) Добавление новой строки только после выхода из редактирования предыдущей новой. Это приводит к тому, что когда ввёл значение в новую строку и пытаешься его сохранить кликнув по кнопке - кнопка отпрыгивает и надо переводить курсор и заново кликать по кнопке.

Вижу несколько вариантов решения:
- Изменить класс FieldTwoProperty добавив в него события извещения изменения элементов, создания нового элемента и потом прослушивать их.
- Создать кастомный вид коллекции для источника DataGrid
- Вместо DataGrid создать свой UserControl

Какие ещё могут быть варианты? Какое решение будет лучше соответствовать концепциям WPF, MVVM ?
...
Рейтинг: 0 / 0
06.11.2018, 13:28
    #39728497
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld Hasp1) Использование обработчиков событий для отслеживания изменений в DataGrid. Вызов методов VM из CB.
2) Отсутствие у DataGrid события извещения о немедленном изменений значений в ячейке.Честно говоря, в твой код не вчитывался.
Я работал с DataGrid, где каждая строка привязана к VM строки, и мне не требовался CB, не очень понял, для чего он нужен.
Что касается уведомления об изменении текстбокса - делаешь свой CellEditTemplate в виде того же текстбокса и делаешь привязку к модели с немедленным уведомлением свойства (а не по потере фокуса).
...
Рейтинг: 0 / 0
06.11.2018, 13:39
    #39728504
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld Haspсоответствовать концепциям WPF, MVVM ?не нужно пихать концепцию в грид.
Это слишком мелко.
Вы просто доводите компонент штатный до своих хотелок, либо берете готовый
https://docs.telerik.com/devtools/wpf/controls/radgridview/overview2
Компонент должен быть максимально изолирован от остального прикладного кода.
...
Рейтинг: 0 / 0
06.11.2018, 13:43
    #39728507
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld HaspПоэтому не очень подходит для редактирования небольших списочных свойств.они тоже в бд как справочники. Поэтому модель обычно другая.
...
Рейтинг: 0 / 0
06.11.2018, 13:46
    #39728514
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Petro123не нужно пихать концепцию в грид.Как вариант. Я делал одну оболочку для него, это был именно юзерконтрол с СВ (из-за динамической загрузки столбцов, динамического назначения селекторов шаблонов) - но с точки зрения эксплуатации - да, концепция "черный ящик", а снаружи DP для встраивания в MVVM
...
Рейтинг: 0 / 0
06.11.2018, 13:47
    #39728515
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld Haspпредназначен для работы с БД и работает транзакциями.
Да ну, ерунда. Никаких транзакций там нет, и DataGrid вообще не в курсе, откуда пришли данные, и как сохраняются.
Eld HaspТеперь что мне не нравится.
Что мне не нравится сразу же и навскидку: Equals и GetHashCode зависят от значений изменяемых полей. На этом моменте можно долго и весело ловить разные баги (и да, я их ловил). Вышеупомянутые методы в связке должны идентифицировать объект (и балансировать дерево) вне зависимости от жизненного цикла объекта.
...
Рейтинг: 0 / 0
06.11.2018, 13:49
    #39728521
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Сон Веры ПавловныEqualsда. С бд этого вообще не нужно.
...
Рейтинг: 0 / 0
06.11.2018, 13:50
    #39728523
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Shocker.ProPetro123не нужно пихать концепцию в грид.Как вариант. Я делал одну оболочку для него, это был именно юзерконтрол с СВ (из-за динамической загрузки столбцов, динамического назначения селекторов шаблонов) - но с точки зрения эксплуатации - да, концепция "черный ящик", а снаружи DP для встраивания в MVVMя помню. Но редко встречается, когда неизвестно сколько столбцов. У вас проект - динамика.
...
Рейтинг: 0 / 0
06.11.2018, 13:52
    #39728524
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
В субд и ОРМ однозначно идентифицирует объект PK.
...
Рейтинг: 0 / 0
06.11.2018, 14:28
    #39728549
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Shocker.ProEld Hasp1) Использование обработчиков событий для отслеживания изменений в DataGrid. Вызов методов VM из CB.
2) Отсутствие у DataGrid события извещения о немедленном изменений значений в ячейке.Честно говоря, в твой код не вчитывался.
Я работал с DataGrid, где каждая строка привязана к VM строки, и мне не требовался CB, не очень понял, для чего он нужен.
Что касается уведомления об изменении текстбокса - делаешь свой CellEditTemplate в виде того же текстбокса и делаешь привязку к модели с немедленным уведомлением свойства (а не по потере фокуса).С TextBox в ячейке DataGrid пробовал. Там получаются проблемы с редактированием TetxBox - нужно два клика. Первым кликом выделяется ячейка, а вторым входишь в редактировании TextBox.
В новой строке, там по моему, вообще получалось три клика, и какие-то проблемы с добавлением в источник новой строки. Т.е. не получалось сравнить источник DG с источником в модели и определить, что изменения произошли.Сон Веры Павловны.... Да ну, ерунда. Никаких транзакций там нет, и DataGrid вообще не в курсе, откуда пришли данные, и как сохраняются. Я может не правильно выразился. Я имел ввиду, конкретно, вот такой нюанс. Новая строка в DataGrid существует только в нём. В источнике её нет. Поэтому по источнику не получится определить были изменения или нет. В идеале, мне нужно получить такое поведение. При любом изменении в новой строке DG она сразу должна добавиться в источник. И, соответственно, в DG появится снизу другая новая строка.Сон Веры ПавловныЧто мне не нравится сразу же и навскидку: Equals и GetHashCode зависят от значений изменяемых полей... В данном случае мне надо определить были ли внесены изменения в список, для этого мне надо сравнить список из DG и список в модели. Любое расхождение между списками: разное количество элементов, разная их последовательность, любое изменение в одном из свойств. Для последнего я и переопределил Equals. Если такой подход не верен, то как лучше сделать?Petro123не нужно пихать концепцию в грид.
Это слишком мелко.
Вы просто доводите компонент штатный до своих хотелок, либо берете готовый
https://docs.telerik.com/devtools/wpf/controls/radgridview/overview2
Компонент должен быть максимально изолирован от остального прикладного кода.Под одной из концепцией я и имел ввиду "Компонент должен быть максимально изолирован от остального прикладного кода". Это одна из причин почему мне не нравится решение в моём примере.
radgridview - посмотрю, что за зверь. А как довести "компонент штатный до своих хотелок" - не знаю. То ли "хотелок" больше чем возможности штатного элемента, то ли мои возможности и умения значительно ниже моих "хотелок"
...
Рейтинг: 0 / 0
06.11.2018, 14:32
    #39728552
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld Hasp,
Есть грид эксель, и есть грид для субд.
Тебе какой?
ЗЫ в дельфи это 2 разных грида.
...
Рейтинг: 0 / 0
06.11.2018, 14:35
    #39728555
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld Haspразная их последовательность,???
...
Рейтинг: 0 / 0
06.11.2018, 14:35
    #39728556
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld HaspТо ли "хотелок" больше чем возможности штатного элементаДа. DataGrid вообще довольно слабый. Но хорошие гриды стоят денег, а бесплатные - г.
Так что либо платить деньги, либо пилить свой, с маджонгом и гейшами
...
Рейтинг: 0 / 0
06.11.2018, 14:43
    #39728561
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Petro123Eld Hasp,
Есть грид эксель, и есть грид для субд.
Тебе какой?
ЗЫ в дельфи это 2 разных грида.DataDrid из C# + WPF + VS2017
...
Рейтинг: 0 / 0
06.11.2018, 14:44
    #39728562
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld Haspто ли мои возможности
Третья причина в том что ты с базами на вы. А надо на ты.
Без них сложно.
...
Рейтинг: 0 / 0
06.11.2018, 14:45
    #39728564
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Petro123Eld Haspразная их последовательность,???Допустим, в DG поменяли местами первую и вторую строку. То есть элементы те же, но их последовательность другая.
...
Рейтинг: 0 / 0
06.11.2018, 14:46
    #39728565
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld HaspDataDrid из C# + WPF + VS2017я говорил о запросах. Какой нужен?.
Т.к. очередность в коллекции это странно.
...
Рейтинг: 0 / 0
06.11.2018, 14:47
    #39728567
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld HaspДопустим, в DG поменяли местами первую и вторую строку. То есть элементы те же, но их последовательность другая.жмакнули на сортировку?
...
Рейтинг: 0 / 0
06.11.2018, 14:47
    #39728568
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Petro123Eld Haspто ли мои возможности
Третья причина в том что ты с базами на вы. А надо на ты.
Без них сложно.В данном случае в решении, вообще, нет БД. Небольшое приложение - данные из XML файла.
...
Рейтинг: 0 / 0
06.11.2018, 14:49
    #39728571
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld Haspданные из XML файла.а там имеет значение очередность?
...
Рейтинг: 0 / 0
06.11.2018, 14:50
    #39728575
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Petro123Eld HaspДопустим, в DG поменяли местами первую и вторую строку. То есть элементы те же, но их последовательность другая.жмакнули на сортировку?Ну в том числе. Или пользователю, захотелось какую-то строку переместить для своего удобства.
Так как данные в XML, то при любом изменении всё равно надо сохранять весь файл. Поэтому я просто определяю есть изменения или нет. Если есть, то всю инфу пересохраняю.
...
Рейтинг: 0 / 0
06.11.2018, 14:53
    #39728578
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Petro123Eld Haspданные из XML файла.а там имеет значение очередность?Только удобство для пользователя. Так как таких строк может или вообще не быть, или быть много. Они могут не помещаться все на видимом поле. И пользователь может передвинуть их вверх вниз в зависимости от того, что ему нужно видеть в первую очередь.
...
Рейтинг: 0 / 0
06.11.2018, 14:53
    #39728579
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld Hasp,
Мрак.
Короче, ты жить богато и с зарплатой хочешь?
Тогда дальнейшее твое творчество уже наносит вред развитию программиста.
Выкинь xml и этот топик будет не нужен.
Удачи!
Имхо.
...
Рейтинг: 0 / 0
06.11.2018, 14:55
    #39728581
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Shocker.ProEld HaspТо ли "хотелок" больше чем возможности штатного элементаДа. DataGrid вообще довольно слабый. Но хорошие гриды стоят денег, а бесплатные - г.
Так что либо платить деньги, либо пилить свой, с маджонгом и гейшами
Пойду - пилить....
...
Рейтинг: 0 / 0
06.11.2018, 14:56
    #39728583
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Отслеживание изменений в DataGrid
Eld HaspОни могут не помещаться все на видимом поле. И пользователь может передвинуть их вверх вниз в зависимости от того, что ему нужно видеть в первую очередь.а) скроллинг б) доп. Колонка и свойство Очередность.
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / Отслеживание изменений в DataGrid / 25 сообщений из 88, страница 1 из 4
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]