Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WPF, Silverlight Новый топик    Ответить
Топик располагается на нескольких страницах: 1 2 3 4      [все]
 Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
DataGrid, как я понял, предназначен для работы с БД и работает транзакциями. Поэтому не очень подходит для редактирования небольших списочных свойств. В инете много разных способов приспособления DataGrid для этих целей, но все они какие-то "корявые".
Поэтому и хотел поинтересоваться, более красивым логичным решением.
Приведу пример и объясню, что мне в нём не нравится.

Класс для элементов списка
  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;
        }
    }
Модель
    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;
        }
    }
Модель представления
 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");
    }
Окно
<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
    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();
        }
    }

Набор классов для работы с командами не прикладываю, он идентичен предоставленному Романом в https://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 ?
6 ноя 18, 13:19    [21725158]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Eld Hasp
1) Использование обработчиков событий для отслеживания изменений в DataGrid. Вызов методов VM из CB.
2) Отсутствие у DataGrid события извещения о немедленном изменений значений в ячейке.
Честно говоря, в твой код не вчитывался.
Я работал с DataGrid, где каждая строка привязана к VM строки, и мне не требовался CB, не очень понял, для чего он нужен.
Что касается уведомления об изменении текстбокса - делаешь свой CellEditTemplate в виде того же текстбокса и делаешь привязку к модели с немедленным уведомлением свойства (а не по потере фокуса).
6 ноя 18, 13:28    [21725171]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
соответствовать концепциям WPF, MVVM ?
не нужно пихать концепцию в грид.
Это слишком мелко.
Вы просто доводите компонент штатный до своих хотелок, либо берете готовый
https://docs.telerik.com/devtools/wpf/controls/radgridview/overview2
Компонент должен быть максимально изолирован от остального прикладного кода.
6 ноя 18, 13:39    [21725186]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Поэтому не очень подходит для редактирования небольших списочных свойств.
они тоже в бд как справочники. Поэтому модель обычно другая.
6 ноя 18, 13:43    [21725195]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Petro123
не нужно пихать концепцию в грид.
Как вариант. Я делал одну оболочку для него, это был именно юзерконтрол с СВ (из-за динамической загрузки столбцов, динамического назначения селекторов шаблонов) - но с точки зрения эксплуатации - да, концепция "черный ящик", а снаружи DP для встраивания в MVVM
6 ноя 18, 13:46    [21725204]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4606
Eld Hasp
предназначен для работы с БД и работает транзакциями.

Да ну, ерунда. Никаких транзакций там нет, и DataGrid вообще не в курсе, откуда пришли данные, и как сохраняются.
Eld Hasp
Теперь что мне не нравится.

Что мне не нравится сразу же и навскидку: Equals и GetHashCode зависят от значений изменяемых полей. На этом моменте можно долго и весело ловить разные баги (и да, я их ловил). Вышеупомянутые методы в связке должны идентифицировать объект (и балансировать дерево) вне зависимости от жизненного цикла объекта.
6 ноя 18, 13:47    [21725206]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Сон Веры Павловны
Equals
да. С бд этого вообще не нужно.
6 ноя 18, 13:49    [21725214]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Shocker.Pro
Petro123
не нужно пихать концепцию в грид.
Как вариант. Я делал одну оболочку для него, это был именно юзерконтрол с СВ (из-за динамической загрузки столбцов, динамического назначения селекторов шаблонов) - но с точки зрения эксплуатации - да, концепция "черный ящик", а снаружи DP для встраивания в MVVM
я помню. Но редко встречается, когда неизвестно сколько столбцов. У вас проект - динамика.
6 ноя 18, 13:50    [21725218]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
В субд и ОРМ однозначно идентифицирует объект PK.
6 ноя 18, 13:52    [21725220]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Shocker.Pro
Eld Hasp
1) Использование обработчиков событий для отслеживания изменений в 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 - посмотрю, что за зверь. А как довести "компонент штатный до своих хотелок" - не знаю. То ли "хотелок" больше чем возможности штатного элемента, то ли мои возможности и умения значительно ниже моих "хотелок"
6 ноя 18, 14:28    [21725273]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp,
Есть грид эксель, и есть грид для субд.
Тебе какой?
ЗЫ в дельфи это 2 разных грида.
6 ноя 18, 14:32    [21725278]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
разная их последовательность,
???
6 ноя 18, 14:35    [21725288]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Eld Hasp
То ли "хотелок" больше чем возможности штатного элемента
Да. DataGrid вообще довольно слабый. Но хорошие гриды стоят денег, а бесплатные - г.
Так что либо платить деньги, либо пилить свой, с маджонгом и гейшами
6 ноя 18, 14:35    [21725290]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp,
Есть грид эксель, и есть грид для субд.
Тебе какой?
ЗЫ в дельфи это 2 разных грида.
DataDrid из C# + WPF + VS2017
6 ноя 18, 14:43    [21725300]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
то ли мои возможности

Третья причина в том что ты с базами на вы. А надо на ты.
Без них сложно.
6 ноя 18, 14:44    [21725301]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
разная их последовательность,
???
Допустим, в DG поменяли местами первую и вторую строку. То есть элементы те же, но их последовательность другая.
6 ноя 18, 14:45    [21725305]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
DataDrid из C# + WPF + VS2017
я говорил о запросах. Какой нужен?.
Т.к. очередность в коллекции это странно.
6 ноя 18, 14:46    [21725306]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Допустим, в DG поменяли местами первую и вторую строку. То есть элементы те же, но их последовательность другая.
жмакнули на сортировку?
6 ноя 18, 14:47    [21725309]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
то ли мои возможности

Третья причина в том что ты с базами на вы. А надо на ты.
Без них сложно.
В данном случае в решении, вообще, нет БД. Небольшое приложение - данные из XML файла.
6 ноя 18, 14:47    [21725311]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
данные из XML файла.
а там имеет значение очередность?
6 ноя 18, 14:49    [21725315]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Допустим, в DG поменяли местами первую и вторую строку. То есть элементы те же, но их последовательность другая.
жмакнули на сортировку?
Ну в том числе. Или пользователю, захотелось какую-то строку переместить для своего удобства.
Так как данные в XML, то при любом изменении всё равно надо сохранять весь файл. Поэтому я просто определяю есть изменения или нет. Если есть, то всю инфу пересохраняю.
6 ноя 18, 14:50    [21725320]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
данные из XML файла.
а там имеет значение очередность?
Только удобство для пользователя. Так как таких строк может или вообще не быть, или быть много. Они могут не помещаться все на видимом поле. И пользователь может передвинуть их вверх вниз в зависимости от того, что ему нужно видеть в первую очередь.
6 ноя 18, 14:53    [21725323]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp,
Мрак.
Короче, ты жить богато и с зарплатой хочешь?
Тогда дальнейшее твое творчество уже наносит вред развитию программиста.
Выкинь xml и этот топик будет не нужен.
Удачи!
Имхо.
6 ноя 18, 14:53    [21725324]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Shocker.Pro
Eld Hasp
То ли "хотелок" больше чем возможности штатного элемента
Да. DataGrid вообще довольно слабый. Но хорошие гриды стоят денег, а бесплатные - г.
Так что либо платить деньги, либо пилить свой, с маджонгом и гейшами

Пойду - пилить....
6 ноя 18, 14:55    [21725328]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Они могут не помещаться все на видимом поле. И пользователь может передвинуть их вверх вниз в зависимости от того, что ему нужно видеть в первую очередь.
а) скроллинг б) доп. Колонка и свойство Очередность.
6 ноя 18, 14:56    [21725331]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 4606
Eld Hasp
Я имел ввиду, конкретно, вот такой нюанс. Новая строка в DataGrid существует только в нём. В источнике её нет. Поэтому по источнику не получится определить были изменения или нет. В идеале, мне нужно получить такое поведение. При любом изменении в новой строке DG она сразу должна добавиться в источник.

Отдельный диалог для ввода новой строки эту проблему вполне решает. И я по возможности стараюсь именно так и делать.
Eld Hasp
В данном случае мне надо определить были ли внесены изменения в список, для этого мне надо сравнить список из DG и список в модели. Любое расхождение между списками: разное количество элементов, разная их последовательность, любое изменение в одном из свойств. Для последнего я и переопределил Equals. Если такой подход не верен, то как лучше сделать?

Ну, Equals сам по себе описанную задачу не решает, он просто проверяет эквивалентность экземпляров классов.
Здесь возникают такие вопросы:
1) Откуда в DG взялся отдельный список? Вы биндите к DG отдельную копию?
2) Если списки различаются - что присходит дальше?
3) Допустим, в списке отображаются фамилия и имя пользователя. В последней строке был Петров Вася. Эту последнюю строку удалили, добавили новую, и снова ввели "Петров" и "Вася". Различия есть? Или нет?
4) Поскольку Equals и GetHashCode зависят от пользовательского ввода, то вполне возможны дублированные записи - т.е. несколько разных элементов списка, которые будут эквивалентны. Что планировалось делать в таком случае?
Eld Hasp
radgridview - посмотрю, что за зверь. А как довести "компонент штатный до своих хотелок" - не знаю. То ли "хотелок" больше чем возможности штатного элемента, то ли мои возможности и умения значительно ниже моих "хотелок"

А вы озвучте хотелки. У стандартного грида есть и группировки, можно прикрутить и фильтрацию, и, возможно, некий наименьший общий знаменатель вполне устроит (меня вот он в 90% случаев устраивает).
Я лично не работал с телериковским гридом, но в случае с гридом от девэкспресса за его мегафункционал всегда приходилось расплачиваться тяжеловесностью UI - просто на уровне отклика UI.
6 ноя 18, 14:58    [21725334]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp,
Мрак.
Короче, ты жить богато и с зарплатой хочешь?
Тогда дальнейшее твое творчество уже наносит вред развитию программиста.
Выкинь xml и этот топик будет не нужен.
Удачи!
Имхо.
Это не кому-то на заказ. Просто появилась возможность (в основном время) заняться освоением WPF и C#. Чтобы не в пустую из головы придумывать задачи, посмотрел, что чуток может помочь в работе. Создаю приложение и учусь на этом.
Пока хочу хоть более-менее WPF и C# освоить. До БД пока... токо смотрю в ту сторону.
6 ноя 18, 15:00    [21725339]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Они могут не помещаться все на видимом поле. И пользователь может передвинуть их вверх вниз в зависимости от того, что ему нужно видеть в первую очередь.
а) скроллинг б) доп. Колонка и свойство Очередность.
Скроллинг - это понятно. Он и так будет.
А вот доп. Колонка - зачем это пользователю? Ему просто надо передвинуть строки вверх-вниз. Доп колонка для него лишнее. А при сохранении всё равно это преимущества не даст, так данные (в доп. колонке) всё рано изменились.
6 ноя 18, 15:04    [21725346]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
А вот доп. Колонка - зачем это пользователю?
ты сам ввел в Модель важное для ТЕБЯ свойство очередность. Разве нет?
6 ноя 18, 15:09    [21725356]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Сон Веры Павловны
Отдельный диалог для ввода новой строки эту проблему вполне решает. И я по возможности стараюсь именно так и делать.
+1
6 ноя 18, 15:11    [21725359]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Создаю приложение и учусь на этом.
делая свой грид но не зная субд?
Это уже перекос будет.
Как для двоих сразу юзверей сделать программу на xml без субд? Без транзакции?
6 ноя 18, 15:13    [21725365]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Сон Веры Павловны
Eld Hasp
Я имел ввиду, конкретно, вот такой нюанс. Новая строка в DataGrid существует только в нём. В источнике её нет. Поэтому по источнику не получится определить были изменения или нет. В идеале, мне нужно получить такое поведение. При любом изменении в новой строке DG она сразу должна добавиться в источник.

Отдельный диалог для ввода новой строки эту проблему вполне решает. И я по возможности стараюсь именно так и делать.
Да, это одно из решений. Так тоже делал. Но мне кажется, "красивее" и удобнее делать это в DataGrid - если возможно, конечно.
Сон Веры Павловны
Eld Hasp
В данном случае мне надо определить были ли внесены изменения в список, для этого мне надо сравнить список из DG и список в модели. Любое расхождение между списками: разное количество элементов, разная их последовательность, любое изменение в одном из свойств. Для последнего я и переопределил Equals. Если такой подход не верен, то как лучше сделать?

Ну, Equals сам по себе описанную задачу не решает, он просто проверяет эквивалентность экземпляров классов.
Здесь возникают такие вопросы:
1) Откуда в DG взялся отдельный список? Вы биндите к DG отдельную копию?
2) Если списки различаются - что присходит дальше?
3) Допустим, в списке отображаются фамилия и имя пользователя. В последней строке был Петров Вася. Эту последнюю строку удалили, добавили новую, и снова ввели "Петров" и "Вася". Различия есть? Или нет?
4) Поскольку Equals и GetHashCode зависят от пользовательского ввода, то вполне возможны дублированные записи - т.е. несколько разных элементов списка, которые будут эквивалентны. Что планировалось делать в таком случае?
1) Да - список в DG это копия списка в модели. Сохранить данные из View можно только явно - нажав на кнопку.
2) Если списки различаются, то становится активной кнопка "Сохранить" и пользователь может сохранить данные. Так же при переходе к другому списку (в данном примере этот функционал не реализован) пользователю выводится предупреждение, что он может потерять данные.
3) По алгоритму это будут считаться одинаковыми списками.
4) Они так и будут дублироваться, пользователя в этом не ограничиваю. Возможно, потом, проверю при пробной эксплуатации, сделаю предупреждение об этом, но ограничивать не буду.
Сон Веры Павловны
Eld Hasp
radgridview - посмотрю, что за зверь. А как довести "компонент штатный до своих хотелок" - не знаю. То ли "хотелок" больше чем возможности штатного элемента, то ли мои возможности и умения значительно ниже моих "хотелок"

А вы озвучте хотелки. У стандартного грида есть и группировки, можно прикрутить и фильтрацию, и, возможно, некий наименьший общий знаменатель вполне устроит (меня вот он в 90% случаев устраивает).

1) При изменении значения любой ячейки сразу (без выхода из фокуса) определить это, чтобы сделать кнопку "Сохранить" активной (это для данного примера, но есть ещё небольшой и другой функционал).
2) При изменении любой ячейки в новой строке, снизу сразу должна появиться другая новая строка.
3) По возможности для решения как можно меньше использовать CB.

Первый, пункт я ещё как-то представляю решение с помощью TextBox в ячейке. При фокусе на ячейке сразу перевести TextBox в режим редактирования. Придётся использовать событие TextBox.TextChanged и обработчик присоединять через EventSetter. Но не знаю насколько хорошее такое решение.

Второй пункт как сделать не знаю. Нужны подсказки. Хотя бы в какую сторону копать.
6 ноя 18, 15:31    [21725387]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
А вот доп. Колонка - зачем это пользователю?
ты сам ввел в Модель важное для ТЕБЯ свойство очередность. Разве нет?
Да, но для этого достаточно, в данном случае, индекса элемента в списке. По нему я и определяю очерёдность. Это нагляднее и удобнее для пользователя.
6 ноя 18, 15:36    [21725396]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Создаю приложение и учусь на этом.
делая свой грид но не зная субд?
Это уже перекос будет.
Как для двоих сразу юзверей сделать программу на xml без субд? Без транзакции?
Пока - да. Освоюсь с WPF буду прикручивать БД. Пока хочу максимально абстрагироваться от способа хранения данных. Чтобы изменив модель можно было ничего другого не трогать. Поэтому и не хочу привязывать DG напрямую к данным. И данная в примере часть, работает только с небольшим списком дополнительных свойств или информации.
Есть ещё другие данные большего объёма, там без БД в многопользовательском режиме не обойтись, пока делаю просто пробную однопользовательскую реализацию. Для самообучения.
6 ноя 18, 15:43    [21725413]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Пока хочу максимально абстрагироваться от способа хранения данных.
не выйдет.
При бд весь твой топик и опыт прямиком в мусор.
А сейчас, на событие отрисовки ЯЧЕЙКИ подставляй data[row, column]
)))
6 ноя 18, 16:19    [21725473]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Пока хочу максимально абстрагироваться от способа хранения данных.
не выйдет.
При бд весь твой топик и опыт прямиком в мусор.
А сейчас, на событие отрисовки ЯЧЕЙКИ подставляй data[row, column]
)))
Я то опыт накапливаю сейчас для работы с WPF и C#. Даже если код не пригодится, опыт-то останется.
Что касается отрисовки, то такое часто применял при работе с WinForms. Там, по сути, по другому и невозможно. Хотелось бы чего-то другого в WPF. Я всё же склоняюсь к UserControl. Мне кажется это лучшее выглядит для WPF.
6 ноя 18, 17:18    [21725587]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Даже если код не пригодится, опыт-то останется.
хороший оксюморон)).
Делайте! Вас все равно не свернуть с пути. Удачи!
6 ноя 18, 17:42    [21725632]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Eld Hasp
Я то опыт накапливаю сейчас для работы с WPF и C#. Даже если код не пригодится, опыт-то останется.
Делай, не слушай Петю, он, похоже, никогда не учился, сразу родился программистом.
Код, написанный два-три года назад, тем более в учебных целях, не пригодится, но опыт будет.
6 ноя 18, 17:45    [21725635]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Shocker.Pro
Eld Hasp
Я то опыт накапливаю сейчас для работы с WPF и C#. Даже если код не пригодится, опыт-то останется.
Делай, не слушай Петю, он, похоже, никогда не учился, сразу родился программистом.
Код, написанный два-три года назад, тем более в учебных целях, не пригодится, но опыт будет.
Ну токо с Вашей помощью! Куда ж я без Вас!
6 ноя 18, 17:56    [21725650]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
DG пофигу на транзакции, это обычный элемент управления и к таблицам БД он имеет посредственное отношение , которое заключается в том, что он поддерживает DataTable класс.
Лично я, по возможности, использую всегда DataGrid, ведь с помощью шаблонов я могу выкинуть из него всё, что хочу. Есть еще вариант ListView, он более легковесный.

В DG всё готово, добавление\редактирование\горизонтальная виртуализация, сортировка и бери и пользуйся, но не без проблем конечно.

При использовании команд, состояние кнопки IsEnabled зависит от выполнения метода CanExecute, по этому у вас кнопка и не включается. Для того, чтоб кнопка обновила статус, нужно вручную вызвать метод CommandManager.InvalidateRequerySuggested() если обновление кнопки подписывается на этот вызов, см. пример ниже
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

или возбудить внутреннее событие кнопки CanExecuteChanged, с её обычной реализацией
        public event EventHandler CanExecuteChanged;

В первом случае учтите, что при таком подходе, вызов метода InvalidateRequerySuggested приведет к проверке всех команд которые подписаны на CommandManager.RequerySuggested. По этому, CanExecute должен быть максимально быстрой операцией.
Можно сделать, проще и дёргать событие ICommand.CanExecuteChanged вручную, либо отслеживать изменение свойств заданной модели представления через INPC внутри команды и возбуждать событие как это сделано во всякие MVVMLight и прочем.

Так же в биндинге источник обновляется по триггеру, который по умолчанию в 99% случаев задан как обновление при потере фокуса, но можно поменять на немедленное обновление.
"{Binding UpdateSourceTrigger=PropertyChanged}"

В примере есть 2 кнопки, настроенные на разные команды, но выполняющие одни и те же методы. У 1 кнопки состояние обновляется, а у второй кнопки нет.

using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Input;

namespace WpfApp18
{
    public abstract class BaseModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChagned(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }

    public class MainModel : BaseModel
    {
        private string _myText;
        public string MyText
        {
            get => _myText;
            set
            {
                if (Equals(_myText, value)) return;
                _myText = value;
                OnPropertyChagned(nameof(MyText));
                MyCommand1.UpdateState();
            }
        }

        private IRelayCommand _myCommand1;
        public IRelayCommand MyCommand1 => _myCommand1 ??
            (_myCommand1 = new RelayCommand(OnMyCommand, CanMyCommand));


        private IRelayCommand _myCommand2;
        public IRelayCommand MyCommand2 => _myCommand2 ??
            (_myCommand2 = new RelayCommand(OnMyCommand, CanMyCommand));


        private bool CanMyCommand(object arg)
        {
            return !string.IsNullOrWhiteSpace(MyText);
        }

        private void OnMyCommand(object obj)
        {
            MessageBox.Show(MyText, "Message");
        }

        public MainModel()
        {

        }
    }


    public interface IRelayCommand : ICommand
    {
        void UpdateState();
    }

    public class RelayCommand : IRelayCommand
    {
        public event EventHandler CanExecuteChanged;

        private readonly Action<object> _onExecute;
        private readonly Func<object, bool> _canExecute;


        public RelayCommand(Action<object> onExecute, Func<object, bool> canExecute)
        {
            _onExecute = onExecute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute?.Invoke(parameter) ?? false;
        }

        public void Execute(object parameter)
        {
            _onExecute?.Invoke(parameter);
        }

        public void UpdateState()
        {
            OnCanExecuteCahgned();
        }

        protected void OnCanExecuteCahgned()
        {
            CanExecuteChanged?.Invoke(this, null);
        }

    }
}

<Window x:Class="WpfApp18.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:WpfApp18"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:MainModel/>
    </Window.DataContext>
    <Grid>
        <StackPanel>
            <TextBox Text="{Binding MyText, UpdateSourceTrigger=PropertyChanged}" Margin="5"/>
            <Button Content="Save" Command="{Binding MyCommand1}" Margin="5,0,5,5"/>
            <Button Content="Save" Command="{Binding MyCommand2}" Margin="5,0,5,5"/>
        </StackPanel>
    </Grid>
</Window>
6 ноя 18, 18:01    [21725655]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Но в целом у меня от WPF впечатление какой-то сыроватости. Вроде, как хорошее начало, идеи, но начинаешь делать то того не хватает, то то как-то по кривому делать приходится, то сложности на пустом месте - какая-то мелочь в сотню строк обходится и т.д.
Ни как не пойму это у меня такое впечатление от нехватки знаний, или оно так и есть?
6 ноя 18, 18:01    [21725656]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Shocker.Pro
Делай, не слушай Петю
детский сад пенсионера не любящего модальных окон)
6 ноя 18, 18:36    [21725701]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Roman Mejtes
DG пофигу на транзакции, это обычный элемент управления и к таблицам БД он имеет посредственное отношение , которое заключается в том, что он поддерживает DataTable класс.
Мне где-то попадалась (не могу найти сейчас) статья о том, как DG вносит изменения в источник. И там было объяснено, что у DG есть какое-то внутреннее представление или буфер для данных. И изменения происходят там. По умолчанию данные скидываются в источник при выходе (потере фокуса) из строки. Можно изменить на скидывание по выходу из ячейки. С новой строкой - только по выходу из строки.
Я не помню как точно - но там было название этого механизма. И транзакцией я его назвал не правильно, просто не смог найти правильного названия.
Roman Mejtes
Лично я, по возможности, использую всегда DataGrid, ведь с помощью шаблонов я могу выкинуть из него всё, что хочу. Есть еще вариант ListView, он более легковесный.

В DG всё готово, добавление\редактирование\горизонтальная виртуализация, сортировка и бери и пользуйся, но не без проблем конечно.
Ага...! То что для Вас "не без проблем" это для меня два дня копания в инете и несколько десятков пробных вариантов.
Roman Mejtes
При использовании команд, состояние кнопки IsEnabled зависит от выполнения метода CanExecute, по этому у вас кнопка и не включается. Для того, чтоб кнопка обновила статус, нужно вручную вызвать метод CommandManager.InvalidateRequerySuggested() если обновление кнопки подписывается на этот вызов
Кнопка у меня включается нормально. Повесил привязку на Button.IsEnabled к свойству VM показывающему о наличии/отсутствии изменений. Это свойство в любом случае у меня есть в VM, так как нужно ещё для другого функционала кроме кнопки. Я этот кусок делал ещё то того как начал знакомится с командами - использовал события. После Вашей помощи начал переделывать. А CanExecute - я просто забыл переделать. Было свойство и я на автомате прибиндил к нему Button.IsEnabled. Для чистоты, раз использую команды, конечно надо переделать. Вы безусловно правы.
Roman Mejtes
Так же в биндинге источник обновляется по триггеру, который по умолчанию в 99% случаев задан как обновление при потере фокуса, но можно поменять на немедленное обновление.
"{Binding UpdateSourceTrigger=PropertyChanged}"
Я знаю об этом триггере, у меня в примере он установлен. Но для "поимки" изменения в источнике, в данном случае это элемент списка, придётся ловить его в самом элементе и потом "проталкивать" до VM - объявить событие в классе элемента и подписать на него VM. А для новой строчки даже это не поможет. Так как новая строчка существует только "внутри" DataGrid.
6 ноя 18, 18:39    [21725706]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Ни как не пойму это у меня такое впечатление от нехватки знаний, или оно так и есть?
есть такое, и пусть Shocker.Pro прыгает от злости. Это эксперимент MS и он всегда может от него отказаться.
6 ноя 18, 18:40    [21725709]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Petro123
детский сад пенсионера не любящего модальных окон)
Да я моложе вас всех вместе взятых! (С)


От модальных окон я отказался по простой причине. Представь, что есть приложение, не хелловорлд, в нем запущено несколько окон на вкладках, к примеру журнал заказов, несколько заказов, карточка клиента и т.п. И одна из этих вкладок вызвала некий диалог. А юзеру чтобы корректно заполнить этот диалог необходимо заглянуть в другое окно, скажем, в журнал доставок. Или звонит клиент, нужно срочно пообщаться с ним по его заказу, а у тебя открыт модальный наполовину заполненный диалог.
Так что модальность мешает и очень сильно. Диалог должен блокировать только тот компонент программы, из которого он вызван, а не все приложение.
6 ноя 18, 18:42    [21725715]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Petro123
есть такое, и пусть Shocker.Pro прыгает от злости. Это эксперимент MS и он всегда может от него отказаться.
Есть мнение, что WPF закончен к версии 4.0. В 4.5 были лишь косметические изменения, по сравнению с предыдущими версиями.
6 ноя 18, 18:44    [21725718]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Мне где-то попадалась (не могу найти сейчас) статья о том, как DG вносит изменения в источник. И там было объяснено, что у DG есть какое-то внутреннее представление или буфер для данных. И изменения происходят там. По умолчанию данные скидываются в источник при выходе (потере фокуса) из строки. Можно изменить на скидывание по выходу из ячейки. С новой строкой - только по выходу из строки.
Я не помню как точно - но там было название этого механизма. И транзакцией я его назвал не правильно, просто не смог найти правильного названия.
это наверно dataSet. Но тут WPF уже по другому.
6 ноя 18, 18:46    [21725719]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
Eld Hasp,

это не буфер, а так называемое представление коллекции (ICollectionView)
для списочных типов используется ListCollectionView, именно там реализован интерфейс IEditableCollectionViewAddNewItem добавление элементов в источник.
Который и поддерживается в DataGrid.
Для любой коллекции в рамках потока существует представление коллекции по умолчанию, через которое работает DataGrid, если источником является класс наследующий IEnumerable, но если создать собственный экземпляр представления и связать его с ItemSource, то будет использоваться именно он.
Представление коллекции так же реализует сортировку, фильтрацию списка, синхронизацию текущего элемента, навигацию и другой функционал.
6 ноя 18, 18:51    [21725726]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Roman Mejtes
Eld Hasp,

это не буфер, а так называемое представление коллекции (ICollectionView)
для списочных типов используется ListCollectionView, именно там реализован интерфейс IEditableCollectionViewAddNewItem добавление элементов в источник.
Который и поддерживается в DataGrid.
Для любой коллекции в рамках потока существует представление коллекции по умолчанию, через которое работает DataGrid, если источником является класс наследующий IEnumerable, но если создать собственный экземпляр представления и связать его с ItemSource, то будет использоваться именно он.
Представление коллекции так же реализует сортировку, фильтрацию списка, синхронизацию текущего элемента, навигацию и другой функционал.
Так как "выловить" изменение ячейки до выхода из неё?
И как быть с новой строкой? Можно ли сделать что-то с этим?
6 ноя 18, 18:58    [21725736]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Так как "выловить" изменение ячейки до выхода из неё?
на ввод каждой буквы. Тебе зачем? Сохраняется запись целиком.
6 ноя 18, 19:05    [21725748]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Roman Mejtes
Есть еще вариант ListView, он более легковесный.
+1. Но автор молчит на предложение.
6 ноя 18, 19:12    [21725755]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Petro123
на ввод каждой буквы. Тебе зачем? Сохраняется запись целиком.
Если ты не встречался с юзеркейсом, это не значит, что его не существует

К сообщению приложен файл. Размер - 2Kb
6 ноя 18, 19:14    [21725758]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Shocker.Pro
Есть мнение, что WPF
ОК. Пару лет понаблюдаем.
6 ноя 18, 19:14    [21725759]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959


К сообщению приложен файл. Размер - 2Kb
6 ноя 18, 19:15    [21725760]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Так как "выловить" изменение ячейки до выхода из неё?
на ввод каждой буквы. Тебе зачем? Сохраняется запись целиком.
Допустим, пользователь отредактировал только одну только одну ячейку DataGrid (Изменил номер телефона, например). Больше ему ни чего менять не надо. Хочет сохранить. Но кнопка "Сохранить" не активна, так как пользователь ещё не вышел из ячейки.
Конечно, можно сделать кнопку всегда активной. А сохранять только если были изменения. Можно сказать пользователю - "Сначала нажмите Enter" и т.д. Но интересно добиться всё таки желаемого. Хотя бы с познавательной точки зрения.
6 ноя 18, 19:17    [21725764]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Shocker.Pro
Если ты не встречался с юзеркейсом, это не значит, что его не существует
плохо видно к чему это.
Запись в табле это обычно сущность.
А сущность частями не сохраняется.
6 ноя 18, 19:18    [21725765]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Но кнопка "Сохранить" не активна, так как пользователь ещё не вышел из ячейки.
не понял. Должна быть активной на вход в редактирование или на ввод одной буквы.
6 ноя 18, 19:20    [21725768]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Roman Mejtes
Есть еще вариант ListView, он более легковесный.
+1. Но автор молчит на предложение.
Я не молчу, а обдумываю. Как быть с новой строкой? Просто явно её добавлять в коллекцию? Коллекцию настроить так, чтобы в ней всегда была одна пустая строка?
Кстати, читал такой вариант для DataGrid. Выловить событие начала редактирования новой строки (PreparingCellForEdit) и по нему явно создать в коллекции новую строку.
6 ноя 18, 19:21    [21725772]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Но кнопка "Сохранить" не активна, так как пользователь ещё не вышел из ячейки.
не понял. Должна быть активной на вход в редактирование или на ввод одной буквы.
До редактирования кнопка "Сохранить" не активна. При любых изменениях становится активной. Желательно, чтобы изменения "ловились" сразу, до выхода из первой ячейки. Так как иначе создаются неудобства в случае редактирования только одной ячейки - а это будет один из частых используемых способов.
6 ноя 18, 19:25    [21725777]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Petro123
пропущено...
не понял. Должна быть активной на вход в редактирование или на ввод одной буквы.
До редактирования кнопка "Сохранить" не активна. При любых изменениях становится активной. Желательно, чтобы изменения "ловились" сразу, до выхода из первой ячейки. Так как иначе создаются неудобства в случае редактирования только одной ячейки - а это будет один из частых используемых способов.
я же сказал, событие ввода буквы. А не выход.
6 ноя 18, 19:28    [21725783]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Как быть с новой строкой?

DataGridTest.Items.Add(
Было?
6 ноя 18, 19:33    [21725793]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Petro123
Eld Hasp
Как быть с новой строкой?

DataGridTest.Items.Add(
Было?
Кури внимательно то, что написал Роман. Нет никакого Add
6 ноя 18, 19:35    [21725794]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
пропущено...
До редактирования кнопка "Сохранить" не активна. При любых изменениях становится активной. Желательно, чтобы изменения "ловились" сразу, до выхода из первой ячейки. Так как иначе создаются неудобства в случае редактирования только одной ячейки - а это будет один из частых используемых способов.
я же сказал, событие ввода буквы. А не выход.
Да, при изменении любого символа, даже если не было выхода.
6 ноя 18, 19:35    [21725795]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Как быть с новой строкой?

DataGridTest.Items.Add(
Было?
Нет. Но если источник прибинден к ItemsSource разве Items.Add исключение не выдаст? Или Вы что-то другое имели ввиду?
6 ноя 18, 19:38    [21725798]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
Eld Hasp
Roman Mejtes
Eld Hasp,

это не буфер, а так называемое представление коллекции (ICollectionView)
для списочных типов используется ListCollectionView, именно там реализован интерфейс IEditableCollectionViewAddNewItem добавление элементов в источник.
Который и поддерживается в DataGrid.
Для любой коллекции в рамках потока существует представление коллекции по умолчанию, через которое работает DataGrid, если источником является класс наследующий IEnumerable, но если создать собственный экземпляр представления и связать его с ItemSource, то будет использоваться именно он.
Представление коллекции так же реализует сортировку, фильтрацию списка, синхронизацию текущего элемента, навигацию и другой функционал.
Так как "выловить" изменение ячейки до выхода из неё?
И как быть с новой строкой? Можно ли сделать что-то с этим?

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

            {
                new Person("Roman", 3),
                new Person("Sofia", 39),
            };

            PersonesView = new ListCollectionView(Persones);
            var i = PersonesView as IEditableCollectionViewAddNewItem;


интерфейс IEditableObject позволит обрабатывать события начала, завершения и отмены редактирования в самом редактируемом объекте модели представления

    public class Person : BaseModel, IEditableObject
    {
        //Данный конструктор класса нужен для автоматического создания новый элементов в DataGrid
        public Person() { }

        public Person(string name, int age)
        {
            Name = name;
            Age = age;
        }

        public string Name { set; get; }
        public int Age { set; get; }

        public void BeginEdit()
        {
            Debug.Print($"Person: {this} Begin Edit");
        }

        public void CancelEdit() 
        {
            Debug.Print($"Person: {this} Cancel Edit");
        }

        public void EndEdit()
        {
            Debug.Print($"Person: {this} End Edit");
        }

        public override string ToString()
        {
            return $"Person: {Name}, {Age}";
        }
    }

Так же можно отслеживать состояния представления коллекции, примерно следующим образом
        
            Persones = new ObservableCollection<Person>()
            {
                new Person("Roman", 3),
                new Person("Sofia", 39),
            };

            PersonesView = new ListCollectionView(Persones);
            if (PersonesView is INotifyPropertyChanged ipc)
            {
                ipc.PropertyChanged += ICV_PropertyChanged;
            }

        private void IECVANI_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (!(sender is IEditableCollectionViewAddNewItem editable)) return;
            Debug.Write($"Changed property '{e.PropertyName}':");
            switch (e.PropertyName)
            {
                    //ADD
                case nameof(IEditableCollectionView.CurrentAddItem):
                    Debug.Write(editable.CurrentAddItem); break;
                case nameof(IEditableCollectionView.IsAddingNew):
                    Debug.Write(editable.IsEditingItem); break;
                case nameof(IEditableCollectionView.CanAddNew):
                    Debug.Write(editable.CanAddNew); break;
                case nameof(IEditableCollectionViewAddNewItem.CanAddNewItem):
                    Debug.Write(editable.CanAddNewItem); break;
                    //EDIT
                case nameof(IEditableCollectionView.CurrentEditItem):
                    Debug.Write(editable.CurrentEditItem);
                    break;
                case nameof(IEditableCollectionView.IsEditingItem):
                    Debug.Write(editable.IsEditingItem); break;
                case nameof(IEditableCollectionView.CanCancelEdit):
                    Debug.Write(editable.CanCancelEdit); break;
                case nameof(IEditableCollectionView.CanRemove):
                    Debug.Write(editable.CanRemove); break;
            }
            Debug.WriteLine(null);

        }
6 ноя 18, 19:38    [21725799]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Но если источник прибинден к ItemsSource разве Items.Add исключение не выдаст?
проверь. Я удивлюсь.
6 ноя 18, 19:40    [21725801]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
естественно, создавай свой ListCollectionView, именно его и нужно передавать как источник элементов в свойство ItemSource
6 ноя 18, 19:40    [21725803]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Eld Hasp
Нет. Но если источник прибинден к ItemsSource разве Items.Add исключение не выдаст? Или Вы что-то другое имели ввиду?
был ли топикстартеру полезен хотя бы один пост Петро?
6 ноя 18, 19:43    [21725805]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Shocker.Pro
Eld Hasp
Нет. Но если источник прибинден к ItemsSource разве Items.Add исключение не выдаст? Или Вы что-то другое имели ввиду?
был ли топикстартеру полезен хотя бы один пост Петро?
партсобрание?
Был ли полезен хоть один твой пост?
Или ты из группы поддержки?
6 ноя 18, 19:46    [21725807]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19959
Мне жаль его время
6 ноя 18, 19:49    [21725808]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Shocker.Pro
Мне жаль его время

А мне жаль когды ты советуешь модифицировать грид)
Почему и говорю - пенсионер.
6 ноя 18, 19:54    [21725813]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Roman Mejtes
интерфейс IEditableObject позволит обрабатывать события начала, завершения и отмены редактирования в самом редактируемом объекте модели представления

Спасибо за пример.
Правильно я понял, что это ниже альтернатива, хотя и за деньги?
<telerik:RadGridView BeginningEdit="radGridView_BeginningEdit"
             RowEditEnded="radGridView_RowEditEnded">
    <!--...-->
</telerik:RadGridView>
6 ноя 18, 20:01    [21725820]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Но если источник прибинден к ItemsSource разве Items.Add исключение не выдаст?
проверь. Я удивлюсь.
Проверил - исключение.

К сообщению приложен файл. Размер - 78Kb
6 ноя 18, 20:34    [21725853]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Roman Mejtes
естественно, создавай свой ListCollectionView, именно его и нужно передавать как источник элементов в свойство ItemSource
Не совсем понял пример.

ipc.PropertyChanged += ICV_PropertyChanged;

private void IECVANI_PropertyChanged(object sender, PropertyChangedEventArgs e)

Это описка или речь о разных обработчиках?
6 ноя 18, 20:47    [21725866]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Roman Mejtes
Eld Hasp
пропущено...
Так как "выловить" изменение ячейки до выхода из неё?
И как быть с новой строкой? Можно ли сделать что-то с этим?

редактируемая ячейка существует только во View, механизм там просто, извлекается значение ячейки, создается ячейка с TextBox, этому TextBox присваивается это значение, а когда вы завершаете редактирование, значение передается в источник. То есть, пока редактирование не завершится, то есть редактируемая ячейка не закроется, получить значение будет довольно геморойно и не особо нужно.
То что геморройно я понял.... Вот такие мелки нюансы в WPF, превращающиеся в геморрой, и удивляют...
6 ноя 18, 20:51    [21725868]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Eld Hasp
Проверил - исключение.

хмм. )) насколько я понял эту фичу которую нужно было зазубрить а не логикой понять.
Добавлять нужно в Модели\Коллекции.
А изменения вверх к гриду придут.
6 ноя 18, 23:04    [21725939]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Petro123
Eld Hasp
Проверил - исключение.

хмм. )) насколько я понял эту фичу которую нужно было зазубрить а не логикой понять.
Добавлять нужно в Модели\Коллекции.
А изменения вверх к гриду придут.
Да, я за это и писал. Если идёт привязка ItemsSource, то изменять надо привязанную коллекцию, а не сам элемент.
6 ноя 18, 23:52    [21725975]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
То что геморройно я понял.... Вот такие мелки нюансы в WPF, превращающиеся в геморрой, и удивляют...
не знаю, я не вижу никакого геморроя, я вижу огромный горизонт применения представления коллекций. по сути это прослойка между View и ViewModel, позволяющая синхронизировать View и ViewMode в плане коллекций, но не только это.
Просто вы плохо еще знакомы с WPF, по этому все кажется сложным, не логичным, когда освоитесь, будет значительно проще. "Магия" декларативного программирования WPF имеет тёмную сторону, если вы плохо понимаете как устроена эта "магия", тяжело, что то реализовать. Разберитесь с основами WPF, иерархией классов, как устроенно связывание, макетирование, маршрутизация событий, векторная графика и аффинные (матричные) преобразования, диспатчер и приоритеты, свойства зависимости и присоединяемые свойства, анимация, триггеры и менеджер состояний, типы ресурсов и чем они отличаются (Dynamic\Static).
В книгах найдете ответы, на все эти вопросы.

Вот лично я вкусив все прелести WPF когда открываю WF проекты, чувствую как снизу печёт =) мне кажется, что я из рая, вернулся в АД, добавить функционал в элемент управления, особенно не свой, это геморой, codebehind файлы по 5000 строк, горите в АДу :)

Petro123, изменять нужно не в коллекции, а её представлении, а после подтверждения Commit'а добавлять элемент в модель представления. В модели представления механизм синхронизации зависит от модели. Либо сразу изменения применяются, либо ко команде Save, либо еще как. На самом деле, ListBox можно заполнить элементами, при этом в модели и модели представления никаких элементов не будет, все они будут "виртуальными", не материализованными даже на уровне VM. Представление коллекции позволяет на уровне View или ViewModel отобразить коллекцию в том виде, в каком требуется, не меняя самой коллекции модели. ListCollectionView позволяет добавить только 1 элемент и только в начало или конец, но этот функционал можно расширить.
Допустим с помощью представления коллекции можно отобразим дерево элементов, отображаться будут только те элементы, родитель которых имеет свойство IsExpanded. Под каждым кустом можно добавить элемент создания дочерних элементов. При этом, если делать это в DataGrid, а вед в нём не обязательны ячейки, можно оставить только строки :D вы получите дерево, если колонки будут, то дерево с колонками и ячейками.
Обернем в шаблоне ItemsPresenter в Popup окно, добавим ToggleButton и получаем ComboBox с деревом, мультиселектом, колонками, сортировкой, фильтрацией, генерацией, редактированием, виртуализацией, синхронизацией и т.д. И по сути, это всё из коробки, собственный код, это только ViewModel, ICollectionView и шаблон элемента, который я могу использовать для любых коллекций, даже без учёта иерархии.
И самый сок в том, что выглядеть это может так как хочет дизайнер, а не как хочет система.
Вот за это я и люблю WPF.
6 ноя 18, 23:56    [21725977]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Eld Hasp
Member

Откуда:
Сообщений: 178
Roman Mejtes
То что геморройно я понял.... Вот такие мелки нюансы в WPF, превращающиеся в геморрой, и удивляют...
не знаю, я не вижу никакого геморроя, я вижу огромный горизонт применения .........
Вот за это я и люблю WPF.
Может я к вам присоединюсь, когда у меня будет 10-я частью Ваших знаний. Но пока ..... Всё так сложно.
Пытаюсь учиться, читать, но как-то всё сложно, запутано. Ни как структура всего этого в голове не уложиться. Может литература не та попадается, а может .... голова не та...
7 ноя 18, 00:41    [21726007]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Roman Mejtes,
Это круто конечно.
Но много крутых задумок закончились ничем, т.к. Кастомизация или допиливание представления нужно в одном из тысячи проектов.
Прокомментируй подход телерика что я выше привел.
Верно что ты привел один вариант, а у телерика второй?
7 ноя 18, 07:12    [21726056]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
Petro123
Roman Mejtes,
Это круто конечно.
Но много крутых задумок закончились ничем, т.к. Кастомизация или допиливание представления нужно в одном из тысячи проектов.
Прокомментируй подход телерика что я выше привел.
Верно что ты привел один вариант, а у телерика второй?
не знаю, не знаю, у меня это обычно в любом проекте. Так как дизайн обычно "дизайнерский", а интерфейс сложнее блокнота.
да и практически любые списки делаю через декораторы, так как мне удобнее хранить состояния выделения и другие состояния в декораторе, а не классах модели представления
7 ноя 18, 11:17    [21726313]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Roman Mejtes
не знаю, не знаю, у меня это обычно в любом проекте.

Странно. Грид девок или телерик позволяет настроить в широких пределах даже джуну.
НЕ имея твоей квалификации.
Интересно конкретнее про ГУИ, если есть желание.
7 ноя 18, 11:44    [21726375]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
Petro123,

я почти не юзал телериковский грид. но в свое время искали SpreedSheet для решения одной задачи и самый прикол в том, что я из всех представленных (Telerik, ComponentOne и другие) я не нашел не одного адекватного, во всех вариантах я находил кучи блокирующих багов и практически все тормозили :( (это не антиреклама, возможно за эти 2 года всё стало лучше)

Но вообще, я только за, если в проекте есть платные компоненты, ведь по факту мне работы меньше, если конечно они подходят для поставленных задач.

по конкретным GUI, не очень понял вопрос, что интересует конкретно?
7 ноя 18, 11:55    [21726404]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Roman Mejtes
по конкретным GUI, не очень понял вопрос, что интересует конкретно?
выше писал как в телерике подписываться на начало редактирования. Твое мнение?
7 ноя 18, 12:08    [21726463]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
а как из модели подписаться на события во View и зачем это нужно?
7 ноя 18, 16:28    [21727075]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Roman Mejtes
а как из модели подписаться на события во View и зачем это нужно?
если ты про мой вопрос, то...
Паттерн MVVM.
В классе ViewModel делаем boolean properties IsEdit. Т.е. Кнопку сохранить биндим на свойство.
А вот кол выше передает событие начала редактирования в метод рядом тут же чтобы взводить это свойство.
Выходить 3 строки кода. Так?
7 ноя 18, 16:49    [21727106]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 3171
привязать кнопку с свойству?
у вас всё сводится, почему то к тому, что чем меньше кода, тем лучше. Но это заблуждение с вашей стороны
8 ноя 18, 10:16    [21727777]     Ответить | Цитировать Сообщить модератору
 Re: Отслеживание изменений в DataGrid  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 37082
Roman Mejtes
привязать кнопку с свойству?
у вас всё сводится, почему то к тому, что чем меньше кода, тем лучше. Но это заблуждение с вашей стороны
аргументируй. Не только меньше кода. Джуны ругаются на сложность)))
8 ноя 18, 10:33    [21727802]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: 1 2 3 4      [все]
Все форумы / WPF, Silverlight Ответить