Гость
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / DataContext биндинг. / 25 сообщений из 30, страница 1 из 2
30.11.2018, 14:56
    #39740948
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
В VM есть следующие свойства
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
        private List<Client> clients;
        public List<Client> Clients { get => clients; set { clients = value; OnPropertyChanged(); } }


        private Client _selectedClient;
        public Client SelectedClient
        {
            get => _selectedClient;
            set
            {
                _selectedClient = value;
                if (!IsEdit) CurrentClient = SelectedClient;
                OnPropertyChanged();
            }
        }

        private Client _currentClient;
        public Client CurrentClient { get => _currentClient; set { _currentClient = value; OnPropertyChanged(); } }

        private bool _isEdit;
        public bool IsEdit { get => _isEdit; set { if (_isEdit && !value) CurrentClient = SelectedClient; _isEdit = value; OnPropertyChanged(); } }

В обычном режиме (IsEdit=false) в CurrentClient копируется значение SelectedClient.
В окне к свойству Name свойства CurrentClient привязан TextBox следующим образом
Код: xml
1.
2.
3.
4.
        <StackPanel Margin="10" Grid.Column="1" DataContext="{Binding CurrentClient}">
            <TextBlock Text="ФИО Клиента"/>
            <TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>

Если в режиме редактирования (IsEdit=true) CurrentClient в методе присваиваю другое значение и потом вносятся какие-либо изменения в TextBox'е, то все привязки в окне рушатся.
Если привязать так
Код: xml
1.
2.
3.
4.
        <StackPanel Margin="10" Grid.Column="1">
            <TextBlock Text="ФИО Клиента"/>
            <TextBox Text="{Binding CurrentClient.Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
        </StackPanel>

То работает нормально, но так привязывать неудобно. У CurrentClient свойств и привязанных к ним элементов много. Удобнее установить общий DataContext в StackPanel.
Чего я не догоняю? Если CurrentClient сделать свойством зависимостей это решит проблему? Или в в чём-то другом проблема?
...
Рейтинг: 0 / 0
30.11.2018, 15:04
    #39740956
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Eld Haspто все привязки в окне рушатся.не смог разгадать смысл фразы
...
Рейтинг: 0 / 0
30.11.2018, 15:17
    #39740971
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Shocker.ProEld Haspто все привязки в окне рушатся.не смог разгадать смысл фразыВ буквальном смысле. Даже привязки не связанные с CurrentClient перестают почему-то работать.
...
Рейтинг: 0 / 0
30.11.2018, 15:18
    #39740973
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Eld Haspпотом вносятся какие-либо изменения в TextBox'е,встречные? От кого?
Я так понял, что поле чисто справочное и биндинг в одну сторону.
...
Рейтинг: 0 / 0
30.11.2018, 15:23
    #39740980
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Окно
Код: 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.
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <DataGrid ItemsSource="{Binding Clients}" AutoGenerateColumns="False" IsReadOnly="True" SelectedItem="{Binding SelectedClient}">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding ID}" ClipboardContentBinding="{x:Null}" Header="ID" Width="*"/>
                <DataGridTextColumn Binding="{Binding Name}" ClipboardContentBinding="{x:Null}" Header="Фамилия, имя, отчество" Width="6*"/>
            </DataGrid.Columns>
        </DataGrid>
        <StackPanel Margin="10" Grid.Column="1" DataContext="{Binding CurrentClient}">
            <TextBlock Text="ФИО Клиента"/>
            <TextBox Text="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding DataContext.IsEdit, ElementName=window}"/>
        </StackPanel>
        <Grid Grid.Row="1" Grid.ColumnSpan="2">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Button  Margin="10" Content="Редактировать" Command="{Binding EditCommand}" />
            <Button Grid.Column="1" Margin="10" Content="Сохранить изменения" Command="{Binding SaveChangeCommand}" CommandParameter="{Binding CurrentClient}"   IsEnabled="{Binding DataContext.IsEdit, ElementName=window}"/>
            <Button Grid.Column="2" Margin="10" Content="Выйти" Command="{Binding ExitCommand}"   IsEnabled="{Binding DataContext.IsEdit, ElementName=window}"/>
        </Grid>
    </Grid>

ViewModel
Код: 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.
82.
83.
    public class ViewModelDSC : OnPropertyChangedClass
    {
        private List<Client> clients;
        public List<Client> Clients { get => clients; set { clients = value; OnPropertyChanged(); } }


        private Client _selectedClient;
        public Client SelectedClient
        {
            get => _selectedClient;
            set
            {
                _selectedClient = value;
                if (!IsEdit) CurrentClient = SelectedClient;
                OnPropertyChanged();
            }
        }

        private Client _currentClient;
        public Client CurrentClient { get => _currentClient; set { _currentClient = value; OnPropertyChanged(); } }

        private bool _isEdit;
        public bool IsEdit { get => _isEdit; set { if (_isEdit && !value) CurrentClient = SelectedClient; _isEdit = value; OnPropertyChanged(); } }


        /// <summary>Поле для хранения значения свойства EditCommand</summary>
        private ICommand _editCommand { get; set; }
        /// <summary>Свойство для привязки команды Редактировать</summary>
        public ICommand EditCommand => _editCommand ?? (_editCommand = new RelayCommand(OnEdit));
        /// <summary>Метод для команды EditCommand</summary>
        protected virtual void OnEdit(object value) { IsEdit = true; CurrentClient = SelectedClient.Copy(); }

        /// <summary>Поле для хранения значения свойства RemoveCommand</summary>
        private ICommand _saveChangeCommand { get; set; }
        /// <summary>Свойство для привязки команды Удалить</summary>
        public ICommand SaveChangeCommand => _saveChangeCommand ?? (_saveChangeCommand = new RelayCommand(OnSaveChange));
        /// <summary>Метод для команды RemoveCommand</summary>
        protected virtual void OnSaveChange(object value)
        {
            MessageBox.Show(value.ToString());
            if (IsEdit && value is Client client)
            {
                if (Model.ChangeID(client))
                {
                    IsEdit = false;
                }
                else
                    System.Windows.MessageBox.Show("Ошибка внесения изменений!");
            }
        }
        /// <summary>Поле для хранения значения свойства EditCommand</summary>
        private ICommand _exitCommand { get; set; }
        /// <summary>Свойство для привязки команды Редактировать</summary>
        public ICommand ExitCommand => _exitCommand ?? (_exitCommand = new RelayCommand(OnExit));
        /// <summary>Метод для команды EditCommand</summary>
        protected virtual void OnExit(object value)
        {
            // Проверка были изменения или нет
            if (IsEdit && !CurrentClient.Equals(SelectedClient))
                // Если были изменения, то вывод предупреждения
                if (MessageBox.Show("Данные не были сохранены!\nПри выходе изменения будут утеряны\nВсё равно выйти?", "Предупреждение!", MessageBoxButton.YesNo)
                     == MessageBoxResult.No)
                    return;
            IsEdit = false;
           
        }


        private ModelDSC _model;

        public ModelDSC Model
        {
            get { return _model; }
            set { _model = value; Clients = Model.GetClients(); }
        }


        public ViewModelDSC() { }
        public ViewModelDSC(string FileName)
        {
            Model = ModelDSC.Load(FileName);
        }
    }

Если войти в режим редактирования, и изменить поле в TextBox, то ни одна привязка после это не работает.
Проект приложил целиком - на всякий случай.
...
Рейтинг: 0 / 0
30.11.2018, 15:25
    #39740983
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Petro123Eld Haspпотом вносятся какие-либо изменения в TextBox'е,встречные? От кого?
Я так понял, что поле чисто справочное и биндинг в одну сторону. Реально несколько полей. В режиме редактирования связь от поля к VM тоже есть.
...
Рейтинг: 0 / 0
30.11.2018, 15:40
    #39741013
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Eld HaspДаже привязки не связанные с CurrentClient перестают почему-то работать.Пока я увидел, что перестает работать привязка к SelectedClient, остальные-то работают, какие привязки перестали еще работать?
...
Рейтинг: 0 / 0
30.11.2018, 15:49
    #39741028
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Shocker.ProEld HaspДаже привязки не связанные с CurrentClient перестают почему-то работать.Пока я увидел, что перестает работать привязка к SelectedClient, остальные-то работают, какие привязки перестали еще работать?там сейчас три привязки. TextBox к CurrentClient.Name, DataGdrid к SelectedClient, параметры в кнопке к CurrentClient.
Остальные, извиняюсь, забыл убрать. Их хотел убрать из примера - забыл. Скинул с ними.
...
Рейтинг: 0 / 0
30.11.2018, 15:51
    #39741032
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
90% виновата перегрузка эквивалентности для Client, в результате которой не порождаются изменения при операциях типа CurrentClient = SelectedClient - объекты по сути разные, но они эквивалентны.
...
Рейтинг: 0 / 0
30.11.2018, 15:52
    #39741033
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
MessageBox в к команде кнопки сохранить должен выводить изменяемый экземпляр Client, а Выводит то с которого делалась копия.
...
Рейтинг: 0 / 0
30.11.2018, 15:53
    #39741036
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Shocker.Pro90% виновата перегрузка эквивалентности для Client, в результате которой не порождаются изменения при операциях типа CurrentClient = SelectedClient - объекты по сути разные, но они эквивалентны.ОК! Попробую сейчас это исправить. Результат отпишу.
...
Рейтинг: 0 / 0
30.11.2018, 16:19
    #39741080
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Eld Haspтам сейчас три привязки.если не заработает, то скрин и use case.
...
Рейтинг: 0 / 0
30.11.2018, 19:13
    #39741252
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Shocker.Pro90% виновата перегрузка эквивалентности для Client, в результате которой не порождаются изменения при операциях типа CurrentClient = SelectedClient - объекты по сути разные, но они эквивалентны.Действительно, для примера это решило все проблемы. Исправлю основной проект - тоже отпишу.
Что-то я упустил такую особенность Equals. В XAML объекты на по адресу, а через этот метод идентифицируются?
Надо перечитать...
...
Рейтинг: 0 / 0
30.11.2018, 19:18
    #39741255
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Eld HaspВ XAML объекты на по адресу, а через этот метод идентифицируются?Возможно, это особенность работы SelectedItem, ибо там коллекция, а какой-нибудь FirstOrDefault будет искать через Equals, я в общем, глубоко не стал копать.
Так или иначе, с целью проверки измененных полей переопределять Equals я бы не стал, потому что это много на что влияет, в частности, как раз на Linq-операции.
...
Рейтинг: 0 / 0
30.11.2018, 19:21
    #39741256
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
С другой стороны...Eld HaspВ XAML объекты на по адресу, а через этот метод идентифицируются?
Надо перечитать...В учебниках я этого не встречал. Но для того, чтобы сгененировать событие изменения свойства зависимости, проверка, возможно, осуществляется через Equals, можно тупо глянуть в исходники.

Отпишись по результатам )
...
Рейтинг: 0 / 0
30.11.2018, 19:23
    #39741258
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Eld Hasp,
Почему выделенный объект не сделать свойство через номер, индекс, айдишник?
...
Рейтинг: 0 / 0
30.11.2018, 19:32
    #39741266
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Petro123Eld Hasp,
Почему выделенный объект не сделать свойство через номер, индекс, айдишник?А зачем его потом разыскивать опять в коллекции, если можно взять непосредственно из свойства?
...
Рейтинг: 0 / 0
30.11.2018, 19:49
    #39741274
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
После исправления Equals основной проект тоже работает как надо.
Спасибо за помощь!
...
Рейтинг: 0 / 0
30.11.2018, 19:53
    #39741275
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Petro123Eld Hasp,
Почему выделенный объект не сделать свойство через номер, индекс, айдишник?Shocker.ProPetro123Eld Hasp,
Почему выделенный объект не сделать свойство через номер, индекс, айдишник?А зачем его потом разыскивать опять в коллекции, если можно взять непосредственно из свойства?
Я не разыскивал его. У меня для редактирования создавалась копия объекта. А перед выходом из редактирования я проверял через Equals были или нет изменения, чтобы сохранить их.
...
Рейтинг: 0 / 0
30.11.2018, 20:22
    #39741289
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Shocker.ProEld HaspВ XAML объекты на по адресу, а через этот метод идентифицируются?Возможно, это особенность работы SelectedItem, ибо там коллекция, а какой-нибудь FirstOrDefault будет искать через Equals, я в общем, глубоко не стал копать.
Так или иначе, с целью проверки измененных полей переопределять Equals я бы не стал, потому что это много на что влияет, в частности, как раз на Linq-операции.Но копия у меня даже не входила в коллекцию. Она у меня создавалась отдельно, только на время редактирования и после него должна была отправляться в мусор.
Даже привязка параметра в команде кнопки уже возвращала не тот объект.
В дебагере же все значения полей VM показывало верно. Влияло именно на привязки в XAML.
...
Рейтинг: 0 / 0
30.11.2018, 20:25
    #39741290
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Shocker.ProА зачем его потом разыскиватьэто взять из коллекции по индексу?
Коллекция же рядом.
...
Рейтинг: 0 / 0
30.11.2018, 20:28
    #39741292
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Eld Haspперед выходом из редактирования я проверял через Equals были или нет изменения, чтобы сохранить их.если есть ORM, DAL то это там делается.
...
Рейтинг: 0 / 0
30.11.2018, 20:33
    #39741295
Petro123
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Eld HaspА перед выходом из редактирования я проверял через Equals были или нет изменения,еще можно флаг bool поставить и взводить при любом редактировании.
Кроме того, другой юзверь поменял, а этот сохраняет СТАРЫЙ объект.
Что делаем?
...
Рейтинг: 0 / 0
30.11.2018, 20:45
    #39741300
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Petro123Eld HaspА перед выходом из редактирования я проверял через Equals были или нет изменения,еще можно флаг bool поставить и взводить при любом редактировании.
Кроме того, другой юзверь поменял, а этот сохраняет СТАРЫЙ объект.
Что делаем?Это учебный однопользовательский проект. Без БД. Данные из XML. Можно разные методы определения модификация создать. Но здесь было проще так. Но столкнулся с неожиданным (для меня) поведением привязок. Переделал. Сейчас работает.
Но причину такой работы привязок так и не понял. Буду разбираться.
...
Рейтинг: 0 / 0
30.11.2018, 20:49
    #39741301
Eld Hasp
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
DataContext биндинг.
Petro123Eld Haspперед выходом из редактирования я проверял через Equals были или нет изменения, чтобы сохранить их.если есть ORM, DAL то это там делается.Не совсем. В данном случае это не относится к данным. Это копия объекта выделенного в View, то есть уровень VM. А ORM, DAL - это уровень модели.
...
Рейтинг: 0 / 0
Форумы / WPF, Silverlight [игнор отключен] [закрыт для гостей] / DataContext биндинг. / 25 сообщений из 30, страница 1 из 2
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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