Caliburn Micro MVVM INotifyPropertyChange

Итак, я использую Cliburn Micro, и у меня есть коллекция Bindable, назовем ее пользователями.

        public BindableCollection<UserModel> Users
    {
        get { return _users; }
        set
        {
            _users = value;
            NotifyOfPropertyChange(() => Users);

        }
    }

Теперь это связано с сеткой данных с двумя столбцами FirstName и LastName. На другой панели устанавливается выбранный элемент сетки данных.

                <DataGrid x:Name = "AllUsers" SelectionMode = "Single" Margin = "5"
                  SelectionUnit = "FullRow" AutoGenerateColumns = "False" 
                  CanUserAddRows = "False" CanUserDeleteRows = "False" 
                  CanUserReorderColumns = "False" 
                  IsReadOnly = "True" Style = "{DynamicResource DataGridUsers}"
                  SelectedItem = "{Binding Path=SelectedUser, Mode=TwoWay}"
                  cal:Message.Attach = "[Event MouseDoubleClick] = [Action DoubleClickUser()]">
                <DataGrid.Columns>
                    <DataGridTextColumn Header = "First Name" Binding = "{Binding Path=FirstName}" Width = "*"/>
                    <DataGridTextColumn Header = "Last Name" Binding = "{Binding Path=LastName}" Width = "*"/>
                </DataGrid.Columns>
            </DataGrid>

Затем я создал TextBoxFirstName и устанавливаю значение только в том случае, если оно не равно null

                            <DockPanel>
                            <Label x:Name = "LabelFirstName" Width = "80" HorizontalContentAlignment = "Left" VerticalAlignment = "Center" Foreground = "#FFAD231F" FontFamily = "Lucida Sans Unicode" FontSize = "12" >First Name</Label>
                            <TextBox x:Name = "TextBoxFirstName" Margin = "0,0,5,0" Text = "{Binding 
                    UpdateSourceTrigger=PropertyChanged, Path=TextBoxFirstName,
                    ValidatesOnDataErrors=true, NotifyOnValidationError=true}" 
                    HorizontalAlignment = "Stretch" Height = "23" TextAlignment = "Center" TextWrapping = "NoWrap" VerticalAlignment = "Top" Style = "{StaticResource RoundedTextBox}" FontFamily = "Lucida Sans Unicode"/>
                        </DockPanel>

Моя проверка ошибок в текстовом поле:

        public string this[string columnName]
    {
        get
        {
            string result = null;
            if (columnName == "TextBoxFirstName")
            {
                if (string.IsNullOrEmpty(TextBoxFirstName))
                {
                    result = "Please enter a First Name";
                }
                else
                {
                    SelectedUser.FirstName = TextBoxFirstName;
                    NotifyOfPropertyChange(() => SelectedUser);
                }

            }
            return result;
        }
    }

Теперь я знаю, что SelectedUser.FirstName обновляется, как если бы я установил привязку данных другого текстового поля к SelectedUser.FirstName, он обновляется, как и ожидалось, но не обновляет Datagrid, когда я его меняю? но если я обновлю значение во втором текстовом поле (с привязкой SelectedUser.FirstName), оно обновит сетку данных,

Есть идеи?? В основном я хочу обновить сетку данных только в том случае, если значение в текстовом поле проходит проверку. Предположим, я не хочу редактировать значения в самой сетке данных.

Сводя меня с ума, я знаю, что это должно быть связано с тем, как он уведомляет, но я не могу заставить его работать, и я довольно новичок в С#, MVVM и WPF, любая помощь будет очень признательна. Спасибо

Реализует ли UserModel INotifyPropertyChanged?

Wes 12.03.2019 22:50

@Wes Если вы имеете в виду выбранного пользователя, то да, это так, public UserModel SelectedUser {get { return _selectedUser; } установить { _selectedUser = значение; Уведомить об изменении свойства (() => выбранный пользователь); } }

Ben 12.03.2019 22:55

Нет, я имел в виду класс User Model, а не свойство Selected User.

Wes 12.03.2019 23:02

Извините, я новичок в этом, чем настройка inotify в пользовательской модели отличается от настройки там, где я ее установил? Разве MVVM не отделяет данные вашей модели от кода, взаимодействующего с представлением? моя точка зрения заключается в том, что он уведомляет другое текстовое поле, которое я установил для SelectedUser.FirstName, но не уведомляет сетку данных, привязанную к тому же самому SelectedUser.FirstName? Можете ли вы привести пример того, что вы имеете в виду?

Ben 12.03.2019 23:13
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
4
483
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам нужно NotifyOfPropertyChange для FirstName вместо SelectedUser. Желательно сделать это в установщике FirstName.

Я пробовал еще { SelectedEmployee.FirstName = TextBoxFirstName; NotifyOfPropertyChange(() => SelectedEmployee.FirstName); } И это все еще не работает?

Ben 12.03.2019 23:01

Вам нужно повысить свойство, измененное внутри пользовательского объекта. Попробуйте поднять свойство, измененное в установщике LastName, всякий раз, когда LastName обновляется. И, конечно же, ваш пользовательский объект должен реализовать INotifyPropertyChanged.

Mark S. 12.03.2019 23:07

Если ваша сетка данных привязана к коллекции объектов UserModel, то UserModel должен реализовать INotifyPropertyChanged, и каждое свойство, которое можно изменить, должно вызывать событие PropertyChanged, передавая имя этого свойства. В противном случае текстовый столбец таблицы данных не будет уведомлен о каких-либо изменениях.

Mark S. 12.03.2019 23:13

Итак, способ, которым я реализовал IDataError, был неправильным, вам не нужно устанавливать значение в операторе else. Как я должен был это реализовать.

Должен был использовать его в моей модели, а не в модели представления.

Также моя модель выглядит так,

namespace App.Models
{
public class ConfigModel : INotifyPropertyChanged
{

    private bool _showConfig;

    public event PropertyChangedEventHandler PropertyChanged;

    public bool ShowConfig
    {

        get { return this._showConfig; }
        set
        {
            this._showConfig = value;
            this.OnPropertyChanged("ShowConfig");
        }
    }

    protected void OnPropertyChanged(string name)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

Спасибо за помощь от Уэса и Марка за то, что указали мне правильное направление.

Другие вопросы по теме