Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.99/116: Рейтинг темы: голосов - 116, средняя оценка - 4.99
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2

INPC (INotifyPropertyChanged) и получение данных из Модели [WPF, Элд Хасп]

27.01.2019, 17:51. Показов 25287. Ответов 63

Лучший ответ Сообщение было отмечено Элд Хасп как решение

Решение

Студворк — интернет-сервис помощи студентам
Тема из цикла Готовые решения, примеры и рекомендации начинающим на WPF [Элд Хасп]

MVVM состоит из трёх раздельных частей. "Знания" этих частей друг о другу ограничены. View знает только о VM, VM только Model, а Model знать никого не желает.

В такой схеме передача данных от View в Model проблем не вызывает. Ограничения есть только для передачи данных от View к VM. Для отправки данных View обращается к Set методу нужного свойства VM (к которому осуществлена привязка), поэтому привязывать свойства View можно только к публичным свойствам VM. Привязать к полям или методам VM невозможно.

Если взять VM из примера в WPF команды и MVVM. Часть 1. пост#15, то свойства First, Second можно упростить до автосвойств и на функционировании приложения это ни как не скажется (сброс свойства Result в данном случае можно опустить)
C#
9
10
public int First { get; set; }
public int Second { get; set; }
Получение же данных происходит иным образом. Так как у VM нет знаний о View, она сама не может "лезть" в View и менять там значения свойств. View сама запрашивает у VM нужные данные вызывая метод Get нужного свойства VM.

Но как определить View, что данные изменились и их надо заново запросить? Для этого VM должна известить View о том какие данные были изменены. Это извещение (событие) для WPF View должно происходить через реализацию интерфейсов INotifyPropertyChanged (INPC) для свойств и INotifyCollectionChanged (INCC) для коллекций (здесь рассматривать не буду).

Дефолтная реализация реализация интерфейса INPC состоит всего из одной строчки
C#
1
public event PropertyChangedEventHandler PropertyChanged;
Но для удобства использования обычно вводят ещё и метод для вызова этого события
C#
1
2
3
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName]string propertyName="") 
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
Атрибут CallerMemberName введён с Framework 4.5. Он позволяет не указывать имя свойства, если вызов происходит из Set метода этого свойства. В указанном примере это используется в свойстве Result
C#
1
2
3
4
5
6
7
8
9
        public int? Result
        {
            get => _result;
            private set
            {
                _result = value;
                OnPropertyChanged();
            }
        }
Использование без параметра OnPropertyChanged() равносильно OnPropertyChanged("Result")

Но только такое использование INPC необязательно. Можно заменить Result на автосвойство и вызывать OnPropertyChanged при записи в него нового значения.
C#
1
2
3
4
5
6
7
8
9
        public int? Result { get; private set;  }
        private void OnCalculate(object parameter)
        {
            if (parameter is OperatorsEnum Operator)
                Result = model.Calculate(First, Operator, Second);
            else
                Result = null;
            OnPropertyChanged("Result");
        }
В указанном в WPF команды и MVVM. Часть 1. пост#15 примере кнопка по сути не нужна. Она была введена для демонстрации команд. Изменим пример - убрав кнопку и используя INPC для обновления Result.

В VM при изменении значений свойств First, Second и SelectOperator будем отправлять в View сообщение об изменении свойства
Result. А в свойстве Result пропишем обращение к свойствам Модели
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
    /// <summary>Класс Модели Представления</summary>
    public class CalcViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName]string propertyName = "")
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        #region Секция свойств 
        private int _first;
        private int _second;
        private OperatorsEnum _selectOperator;
 
        public int First
        {
            get => _first;
            set
            {
                if (_first != value)
                {
                    _first = value;
                    OnPropertyChanged("Result");
                }
            }
        }
        public int Second
        {
            get => _second;
            set
            {
                if (_second != value)
                {
                    _second = value;
                    OnPropertyChanged("Result");
                }
            }
        }
 
        public OperatorsEnum SelectOperator
        {
            get => _selectOperator;
            set
            {
                _selectOperator = value;
                OnPropertyChanged("Result");
            }
        }
 
        public int? Result => model.IsCanExecuteCalculate(First, SelectOperator, Second)
            ? model.Calculate(First, SelectOperator, Second)
            : null;
 
        public IEnumerable<OperatorsEnum> Operators => model.GetOperators();
        #endregion
 
        CalcModel model = new CalcModel(); // Ссылка на модель
    }
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
<Window x:Class="INPCinModel.CalcWindow"
        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:INPCinModel"
        mc:Ignorable="d"
        Title="Калькулятор (Calc)" SizeToContent="WidthAndHeight">
    <Window.DataContext>
        <local:CalcViewModel/>
    </Window.DataContext>
    <StackPanel Orientation="Horizontal">
        <TextBox VerticalAlignment="Center" 
                 Text="{Binding First, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
                 Margin="5" MinWidth="80"/>
        <ComboBox VerticalAlignment="Center" 
                  ItemsSource="{Binding Operators}"
                  SelectedItem="{Binding SelectOperator}"
                  Margin="5" MinWidth="80"/>
        <TextBox Grid.Column="2" VerticalAlignment="Center" 
                 Text="{Binding Second, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
                 Margin="5"  MinWidth="80"/>
        <TextBlock Margin="5" VerticalAlignment="Center" Text="="/>
        <TextBox VerticalAlignment="Center" 
                 Text="{Binding Result, Mode=OneWay}" 
                 Margin="5" IsReadOnly="True" MinWidth="80"/>
    </StackPanel>
</Window>
Рассмотрим теперь полную схему получения данных в MVVM

Если для отправки извещения в View, VM должна реализовывать INPC или INCC, то модель этим не ограничена. Но использование этих интерфейсов в большинстве случаев удобно и позволяет сделать код более прозрачным и читаемым. Можно использовать INPC не совсем стандартно. По своей сути событие PropertyChanged пересылает просто текстовое сообщение (string), ни каких проверок на существование свойства с таким именем не производится. Поэтому не обязательно чтобы параметр метода OnPropertyChanged был названием свойства.
В примере выше, VM обращается к методам Модели сразу возвращающим данные, но такие методы не всегда есть у модели. И если значения свойств First, Second и SelectOperator сразу посылать в Модель, то VM не может знать изменится Result или нет. Для этого при изменении Result Модель должна создать событие извещающее об этом, а VM "прослушивать" это событие и по нему запросить данные.

Пример Модели. В Модели реализованы методы для получения данных от VM: First, Second и SelectOperator. Методы для возвращения данных в VM: GetResult и GetOperators. Для удобства введён дополнительный конструктор сразу подключающий "прослушку" события PropertyChanged.
Имена методов Модели намеренно сделаны не совпадающими с именами свойств VM для большей наглядности взаимодействия. Для этой же цели PropertyChanged сообщает VM об изменении несуществующего свойства ResultChange
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
    /// <summary>Класс модели</summary>
    public class CalcINPCModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName]string propertyName = "")
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 
 
        #region закрытые поля
        private int _first;
        private int _second;
        private OperatorsEnum _selectOperator;
        private int? _result = null;
        #endregion
 
        #region Методы получающие данные
        public void SetFirst(int value)
        {
            if (_first != value)
            {
                _first = value;
                OnResult();
            }
        }
        public void SetSecond(int value)
        {
            if (_second != value)
            {
                _second = value;
                OnResult();
            }
        }
 
        public void SetOperator(OperatorsEnum value)
        {
            if (_selectOperator != value)
            {
                _selectOperator = value;
                OnResult();
            }
        }
        #endregion
 
        #region Методы отправляющие данные
        public int? GetResult() => _result;
 
        /// <summary>Возвращает последовательность значений перечисления OperatorsEnum</summary>
        /// <returns></returns>
        public IEnumerable<OperatorsEnum> GetOperators()
            => Enum.GetValues(typeof(OperatorsEnum)).Cast<OperatorsEnum>();
        #endregion
 
        /// <summary>Обработка полученных данных</summary>
        private void OnResult()
        {
            int? value = null;
            if (_selectOperator != OperatorsEnum.Деление || _second != 0)
                switch (_selectOperator)
                {
                    case OperatorsEnum.Сложение: value = _first + _second; break;
                    case OperatorsEnum.Умножение: value = _first * _second; break;
                    case OperatorsEnum.Вычитание: value = _first - _second; break;
                    case OperatorsEnum.Деление: value = _first / _second; break;
                }
            if (_result != value)
            {
                _result = value;
                OnPropertyChanged("ResultChange");
            }
        }
 
        /// <summary>Безпараметрический конструктор</summary>
        public CalcINPCModel() { }
        /// <summary>Конструктор принимающий делегат для "прослушивания" события PropertyChanged</summary>
        /// <param name="propertyChanged">Делегат для прослушки</param>
        public CalcINPCModel(PropertyChangedEventHandler propertyChanged)
            => PropertyChanged += propertyChanged;
    }
В ViewModel свойства First, Second и SelectOperator ни где не хранят свои значения. При получении изменений от View они сразу отправляют их в методы Модели.
Инициализация Модели сделана через обращение к свойству для подключения прослушки чтобы не создавать конструктор ViewModel. В методе Model_PropertyChanged прослушивающем PropertyChanged проверяется имя свойства, если оно ResultChange, то отправляется извещение в View об изменении свойства Result. Пр обращении View к свойству Result оно получает своё значение от модели.
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
    /// <summary>Класс Модели Представления</summary>
    public class CalcINPCViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName]string propertyName = "")
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        #region Секция свойств 
        public int First { set => model.SetFirst(value); }
        public int Second { set => model.SetSecond(value); }
 
        public OperatorsEnum SelectOperator { set => model.SetOperator(value); }
 
        public int? Result => model.GetResult();
 
        public IEnumerable<OperatorsEnum> Operators => model.GetOperators();
        #endregion
 
        CalcINPCModel _model;
        CalcINPCModel model => _model ?? (_model = new CalcINPCModel(Model_PropertyChanged)); // Ссылка на модель
 
        private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ResultChange")
                OnPropertyChanged("Result");
        }
    }
XAML окна не изменился, но на всякий случай привожу его
Кликните здесь для просмотра всего текста
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
<Window x:Class="INPCinModel.CalcINPCWindow"
        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:INPCinModel"
        mc:Ignorable="d"
        Title="Калькулятор (CalcINPC)" SizeToContent="WidthAndHeight">
    <Window.DataContext>
        <local:CalcINPCViewModel/>
    </Window.DataContext>
    <StackPanel Orientation="Horizontal">
        <TextBox VerticalAlignment="Center" 
                 Text="{Binding First, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
                 Margin="5" MinWidth="80"/>
        <ComboBox VerticalAlignment="Center" 
                  ItemsSource="{Binding Operators}"
                  SelectedItem="{Binding SelectOperator}"
                  Margin="5" MinWidth="80"/>
        <TextBox Grid.Column="2" VerticalAlignment="Center" 
                 Text="{Binding Second, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
                 Margin="5"  MinWidth="80"/>
        <TextBlock Margin="5" VerticalAlignment="Center" Text="="/>
        <TextBox VerticalAlignment="Center" 
                 Text="{Binding Result, Mode=OneWay}" 
                 Margin="5" IsReadOnly="True" MinWidth="80"/>
    </StackPanel>
</Window>


Теперь к такой Модели можно подключить другие View и ViewModel

Модель и первые View+VM почти те же. Добавлена только возможность ссылки на модель через статическое поле.
Добавление в Модели
C#
1
2
        static CalcIWithResultModel _model;
        public static CalcIWithResultModel Model => _model ?? (_model = new CalcIWithResultModel());
Получение Модели в конструкторе VM
C#
1
2
3
4
5
6
        readonly CalcIWithResultModel model;
        public CalcIWithResultViewModel()
        {
            model = CalcIWithResultModel.Model;
            model.PropertyChanged += Model_PropertyChanged;
        }
Целиком коды цепочки "Calc"
Кликните здесь для просмотра всего текста
Модель
Кликните здесь для просмотра всего текста
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
    /// <summary>Класс модели</summary>
    public class CalcIWithResultModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName]string propertyName = "")
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 
        static CalcIWithResultModel _model;
        public static CalcIWithResultModel Model => _model ?? (_model = new CalcIWithResultModel());
 
        #region закрытые поля
        private int _first;
        private int _second;
        private OperatorsEnum _selectOperator;
        private int? _result = null;
        #endregion
 
        #region Методы получающие данные
        public void SetFirst(int value)
        {
            if (_first != value)
            {
                _first = value;
                OnResult();
            }
        }
        public void SetSecond(int value)
        {
            if (_second != value)
            {
                _second = value;
                OnResult();
            }
        }
 
        public void SetOperator(OperatorsEnum value)
        {
            if (_selectOperator != value)
            {
                _selectOperator = value;
                OnResult();
            }
        }
        #endregion
 
        #region Методы отправляющие данные
        public int? GetResult() => _result;
 
        /// <summary>Возвращает последовательность значений перечисления OperatorsEnum</summary>
        /// <returns></returns>
        public IEnumerable<OperatorsEnum> GetOperators()
            => Enum.GetValues(typeof(OperatorsEnum)).Cast<OperatorsEnum>();
        #endregion
 
        /// <summary>Обработка полученных данных</summary>
        private void OnResult()
        {
            int? value = null;
            if (_selectOperator != OperatorsEnum.Деление || _second != 0)
                switch (_selectOperator)
                {
                    case OperatorsEnum.Сложение: value = _first + _second; break;
                    case OperatorsEnum.Умножение: value = _first * _second; break;
                    case OperatorsEnum.Вычитание: value = _first - _second; break;
                    case OperatorsEnum.Деление: value = _first / _second; break;
                }
            if (_result != value)
            {
                _result = value;
                OnPropertyChanged("ResultChange");
            }
        }
 
        /// <summary>Безпараметрический конструктор</summary>
        public CalcIWithResultModel() { }
        /// <summary>Конструктор принимающий делегат для "прослушивания" события PropertyChanged</summary>
        /// <param name="propertyChanged">Делегат для прослушки</param>
    }
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
    /// <summary>Класс Модели Представления</summary>
    public class CalcIWithResultViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName]string propertyName = "")
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 
        #region Секция свойств 
        public int First { set => model.SetFirst(value); }
        public int Second { set => model.SetSecond(value); }
 
        public OperatorsEnum SelectOperator { set => model.SetOperator(value); }
 
        public int? Result => model.GetResult();
 
        public IEnumerable<OperatorsEnum> Operators => model.GetOperators();
        #endregion
 
 
        private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ResultChange")
                OnPropertyChanged("Result");
        }
 
        readonly CalcIWithResultModel model;
        public CalcIWithResultViewModel()
        {
            model = CalcIWithResultModel.Model;
            model.PropertyChanged += Model_PropertyChanged;
        }
    }
Окно
Кликните здесь для просмотра всего текста
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
<Window x:Class="INPCinModel.CalcIWithResultWindow"
        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:INPCinModel"
        mc:Ignorable="d"
        Title="Калькулятор (CalcIWithResult)" SizeToContent="WidthAndHeight">
    <Window.DataContext>
        <local:CalcIWithResultViewModel/>
    </Window.DataContext>
    <StackPanel Orientation="Horizontal">
        <TextBox VerticalAlignment="Center" 
                 Text="{Binding First, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
                 Margin="5" MinWidth="80"/>
        <ComboBox VerticalAlignment="Center" 
                  ItemsSource="{Binding Operators}"
                  SelectedItem="{Binding SelectOperator}"
                  Margin="5" MinWidth="80"/>
        <TextBox Grid.Column="2" VerticalAlignment="Center" 
                 Text="{Binding Second, Mode=OneWayToSource, UpdateSourceTrigger=PropertyChanged}"
                 Margin="5"  MinWidth="80"/>
        <TextBlock Margin="5" VerticalAlignment="Center" Text="="/>
        <TextBox VerticalAlignment="Center" 
                 Text="{Binding Result, Mode=OneWay}" 
                 Margin="5" IsReadOnly="True" MinWidth="80"/>
    </StackPanel>
</Window>

Во второй цепочке "Result" используется упрощённая VM и выводится только результат.
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
    /// <summary>Класс упрощённой ViewModel</summary>
    public class ResultViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void OnPropertyChanged([CallerMemberName]string propertyName = "")
            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 
        public int? Result => model.GetResult();
 
        readonly CalcIWithResultModel model;
        public ResultViewModel()
        {
            model = CalcIWithResultModel.Model;
            model.PropertyChanged += Model_PropertyChanged;
        }
 
 
        private void Model_PropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == "ResultChange")
                OnPropertyChanged("Result");
        }
 
    }
XML
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<Window x:Class="INPCinModel.ResultWindow"
        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:INPCinModel"
        mc:Ignorable="d"
        Title="ResultWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:ResultViewModel/>
    </Window.DataContext>
    <Viewbox>
        <TextBlock Text="{Binding Result}"/>
    </Viewbox>
</Window>
И, конечно, для показа обоих окон надо добавить в App обработчик Startup
C#
1
2
3
4
5
        private void Application_Startup(object sender, StartupEventArgs e)
        {
            (new CalcIWithResultWindow()).Show();
            (new ResultWindow()).Show();
        }
Архив с кодами приложен.
Вложения
Тип файла: zip INPCinModel.zip (100.7 Кб, 260 просмотров)
10
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
27.01.2019, 17:51
Ответы с готовыми решениями:

Библиотека элементов для реализации WPF MVVM Решений [WPF, Элд Хасп]
Решил собрать элементы используемые в темах в этом разделе. В библиотеку включаю элементы которые, на мой взгляд, имеют универсальное...

WPF команды и MVVM. Часть 1. [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Для использования и создания WPF команд в Net предусмотрен...

Передача данных между Окнами, между VM, Шина Сообщений, Локатор [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Использование статического класса. Передача...

63
 Аватар для werymag
27 / 12 / 1
Регистрация: 20.05.2015
Сообщений: 217
04.08.2023, 16:41
Студворк — интернет-сервис помощи студентам
Как я понял WPF передали в опенсорс, а поддержку в какое-то там подразделение, которое занимается поддержкой старых технологий. Если я правильно понял пересказ этой статьи https://medium.com/young-coder... 9ab0424e8c

Но опять же, та же активно развивающаяся Авалония по виду один в один WPF, только кросплотформенная и с вот такими удобностями, как в примере выше. Так что особо проблем в этом не вижу.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
04.08.2023, 16:45  [ТС]
Цитата Сообщение от werymag Посмотреть сообщение
Ну тут скорее то, что теперь уж точно ждать развития особо не стоит, а хотелось бы.
Чёрт его знает.
Я пробовал многие XAML-платформы. Если оценивать все возможности, то до WPF любой из них ещё десяток лет расти.
Возьмите простейший DynamicResource.
Проблема WPF - это "только Win DeskTop".
А доля DeskTop уменьшается.
0
0 / 0 / 0
Регистрация: 23.07.2019
Сообщений: 19
26.04.2024, 12:49
Как выполнить обновление значений во View вложенных свойств класса?

Допустим есть класс Phone со свойством Name. Phone реализует INPC, Name использует OnPropertyChanded() в сеттере.
Во внешнем коде по вызову метода Button_Сlick меняю Name на что-то другое (phone.Name="Apple"), свойство в дебаггере меняется, а во View не обновляется.
0
Модератор
Эксперт .NET
 Аватар для Элд Хасп
16166 / 11286 / 2892
Регистрация: 21.04.2018
Сообщений: 33,176
Записей в блоге: 2
26.04.2024, 23:39  [ТС]
Цитата Сообщение от melisey Посмотреть сообщение
свойство в дебаггере меняется, а во View не обновляется.
Или неверная реализация INPC, или путаница в экземплярах.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.04.2024, 23:39

WPF конвертеры [Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html View получает данные от ViewModel, но часто бывают случаи...

Элемент геометрии «Стрелка» [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Реализация сделана по вопросу отDissolve в теме...

WPF vs WinForms (для начинающих) [Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html Эту тему решил создать, так как очень часто сталкиваюсь с...

WPF команды и MVVM. Часть 2. Всплытие команд. Реализация команды для списка элементов [WPF, Элд Хасп]
Тема из цикла https://www.cyberforum.ru/wpf-silverlight/thread2384523.html На практике часто встречаются случаи когда команда и кнопка...

Обсуждение темы "Библиотека элементов для реализации WPF MVVM Решений" [WPF, Элд Хасп]
Любое обсуждение, рекомендации, вопросы и т.п. по теме https://www.cyberforum.ru/wpf-silverlight/thread2738784.html В том числе по...


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

Или воспользуйтесь поиском по форуму:
64
Ответ Создать тему
Новые блоги и статьи
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
Программа опроса у.з. расходомера SLS-720F
Argus19 02.09.2026
Программа опроса у. з. расходомера SLS-720F Программа опрашивает один раз в минуту три ультразвуковых расходомера SLS-720F через интерфейс RS-485 по протоколу Modbus RTU. Опрашиваются регистры. . .
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru