Форум программистов, компьютерный форум, киберфорум
C#: WPF, UWP и Silverlight
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.67/9: Рейтинг темы: голосов - 9, средняя оценка - 4.67
106 / 87 / 13
Регистрация: 29.08.2012
Сообщений: 539
1

Есть ли способ "автоматического" уведомления о том, что свойство изменилось?

17.04.2015, 12:24. Показов 1748. Ответов 10
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Так обычно выглядит уведомление об изменении некоторого свойства:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        public event PropertyChangedEventHandler PropertyChanged;
 
        protected void NotifyPropertyChanged(string name)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(name));
            }
        }
 
        private string _host;
        public string Host
        {
            get
            {
                return _host;
            }
            private set
            {
                _host = value;
                NotifyPropertyChanged("Host");
            }
        }
Несколько уродливо. Лично меня напрягают два момента:
1. слишкоммногабукаф;
2. нужно писать строку NotifyPropertyChanged("Host"), а конкретно то, что имя свойства может измениться, и я, как самый обыкновенный человек, могу забыть поменять "Host" на новое.
Вопрос простой: есть ли способ лучше? Например, отнаследоваться от чего-либо и писать что-нибудь типа:
C#
1
2
        [Notifitied property]
        public string Host { get; private set; }
Ну или любой другой более "красивый" способ. Про DependencyProperty не писать. Уродство из той же оперы.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
17.04.2015, 12:24
Ответы с готовыми решениями:

Есть ли какой-нибудь способ/программа для автоматического форматирования XAML-кода
Есть ли какой-нибудь способ/программа для автоматического форматирования XAML-кода, т.е. например...

Есть ли способ отображать уведомления браузера Google Chrome в его иконке на панели задач?
Хочу, чтобы уведомления от Хрома отображались на иконке (естественно, когда он запущен). Как...

Механизм автоматического уведомления об изменении данных а-ля 1С
Здравствовать всем! Наверняка есть на форуме плотно работающие со связкой 1С- postgreSQL Если...

Есть ли данные в том что вернуло?
вот допустим у меня запрос к бд: $result = mysql_query("SELECT * FROM user_item WHERE...

Есть ли способ сделать так, что бы мышка в QML не тормозила?
В QML мышка отстаёт от указателя на экране. То есть, допустим, если прицепить какой - то Rectangle...

10
Заблокирован
17.04.2015, 12:30 2
Цитата Сообщение от Kukurudza Посмотреть сообщение
2. нужно писать строку NotifyPropertyChanged("Host"), а конкретно то, что имя свойства может измениться, и я, как самый обыкновенный человек, могу забыть поменять "Host" на новое.
Kukurudza, можно использовать атрибут [CallerMemberName]
https://msdn.microsoft.com/ru-... .110).aspx

Тогда:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public string Host
        {
            get
            {
                return _host;
            }
            private set
            {
                _host = value;
                NotifyPropertyChanged();
            }
        }
...
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
{
...
}
0
Эксперт .NET
1838 / 1346 / 427
Регистрация: 10.06.2011
Сообщений: 2,126
17.04.2015, 13:13 3
Я написал для себя когда-то вот такой вот велосипед (а может быть просто скопипастил откуда-то):
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
public class NotificationObject : INotifyPropertyChanged
{
        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
                return SetProperty(ref storage, value, null, propertyName);
        }
 
        protected virtual bool SetProperty<T>(ref T storage, T value, Action callback, [CallerMemberName] string propertyName = null)
        {
                if (Equals(storage, value))
                        return false;
                storage = value;
                RaisePropertyChanged(propertyName);
                if (callback != null)
                        callback();
                return true;
        }
 
        protected bool SetProperty<T>(ref T? storage, T value, [CallerMemberName] string propertyName = null)
                where T : struct
        {
                return SetProperty(ref storage, value, null, propertyName);
        }
 
        protected virtual bool SetProperty<T>(ref T? storage, T value, Action callback, [CallerMemberName] string propertyName = null)
                where T : struct
        {
                if (Equals(storage, value))
                        return false;
                storage = value;
                RaisePropertyChanged(propertyName);
                if (callback != null)
                        callback();
                return true;
        }
 
        protected virtual T GetProperty<T>(ref T? storage, T defaultValue)
                where T : struct
        {
                if (!storage.HasValue)
                        storage = defaultValue;
                return storage.Value;
        }
 
        protected void RaisePropertyChanged<T>(Expression<Func<T>> action)
        {
                var propertyName = GetPropertyName(action);
                RaisePropertyChanged(propertyName);
        }
 
        private static string GetPropertyName<T>(Expression<Func<T>> action)
        {
                var expression = (MemberExpression)action.Body;
                var propertyName = expression.Member.Name;
                return propertyName;
        }
 
        private void RaisePropertyChanged(string propertyName)
        {
                if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
}
Можно отнаследоваться от него и описывать уведомляемые свойства таким образом:
C#
1
2
3
4
5
6
7
8
9
10
public class A : NotificationObject
{
        private string _name;
 
        public string Name
        {
                get { return _name; }
                set { SetProperty(ref _name, value); }
        }
}
Букв всё равно немало, но сократил, как только смог.
Также можно прописать и обработчик изменений:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class A : NotificationObject
{
        private string _name;
 
        public string Name
        {
                get { return _name; }
                set { SetProperty(ref _name, value, OnNameChanged); }
        }
 
        private void OnNameChanged()
        {
 
        }
}
0
146 / 143 / 32
Регистрация: 21.01.2012
Сообщений: 545
17.04.2015, 13:30 4
Почти каждый фреймворк предлагает свой вариант реализовать INPC на свойствах.
Я пользую такой класс вместо того что ты указал.
Твой лучше работает, но я так понимаю CallerMemberName с fw4.5 только.
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
public abstract class ObservableObject : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propName) {
Debug.Assert(GetType().GetProperty(propName) != null);
var pc = PropertyChanged;
if(pc != null)
pc(this, new PropertyChangedEventArgs(propName));
}
protected bool SetProperty<T>(ref T field, T value,
string propName) {
if(!EqualityComparer<T>.Default.Equals(field, value)) {
field = value;
OnPropertyChanged(propName);
return true;
}
return false;
}
protected bool SetProperty<T>(ref T field, T value,
Expression<Func<T>> expr) {
if(!EqualityComparer<T>.Default.Equals(field, value)) {
field = value;
var lambda = (LambdaExpression)expr;
MemberExpression memberExpr;
if(lambda.Body is UnaryExpression) {
var unaryExpr = (UnaryExpression)lambda.Body;
memberExpr = (MemberExpression)unaryExpr.Operand;
}
else {
memberExpr = (MemberExpression)lambda.Body;
}
OnPropertyChanged(memberExpr.Member.Name);
return true;
}
return false;
}
}
Использование
C#
1
2
3
4
5
string _name;
public string Name {
get { return _name; }
set { SetProperty(ref _name, value, () => Name); }
}
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
20.04.2015, 09:43 5
Kukurudza, используй https://mvvmlight.codeplex.com/releases
Цитата Сообщение от Kukurudza Посмотреть сообщение
1. слишкоммногабукаф;
И потом все классы, требующие уведомлений о изменении свойств наследуй от ViewModelBase и не нужно ничего самому изобретать, там всё грамотно написано изначально.
Миниатюры
Есть ли способ "автоматического" уведомления о том, что свойство изменилось?  
0
879 / 558 / 291
Регистрация: 21.11.2012
Сообщений: 1,553
21.04.2015, 15:00 6
работает безупречно

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*---------notwendige Namespaces-----------*/
        //using System.Runtime.CompilerServices;
        //using System.ComponentModel;
 
        /*---------Schnittstelle implementieren-----------*/
        //Klassenname : INotifyPropertyChanged
 
        // Aufruf in Set-Methoden der Properties
 
        public event PropertyChangedEventHandler PropertyChanged;
 
        private void OnPropertyChanged([CallerMemberName]string propertyName = "")
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
использовать:

C#
1
2
3
4
5
6
7
8
9
10
11
12
public string Host
        {
            get
            {
                return _host;
            }
            private set
            {
                _host = value;
                OnPropertyChanged( );
            }
        }
0
1245 / 1055 / 293
Регистрация: 07.03.2012
Сообщений: 3,245
21.04.2015, 15:05 7
какой то фигнёй страдаете, чем mvvLight не устраивает?
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 private float _fat;
        public float Fat
        {
            get
            {
                return _fat;
            }
            set
            {
                if (_fat == value)
                {
                    return;
                }
                _fat = value;
                RaisePropertyChanged(() => Fat);
            }
        }
0
Эксперт .NET
4432 / 2092 / 404
Регистрация: 27.03.2010
Сообщений: 5,657
Записей в блоге: 1
21.04.2015, 17:48 8
Цитата Сообщение от hamin Посмотреть сообщение
работает безупречно
В MvvmLight это уже есть и тоже не надо писать имя свойства. Только с библиотекой получаешь ещё много полезного функционала. Ладно, я вас не уговариваю, пишите всё полностью сами )

Добавлено через 1 минуту
Монфрид, читал на хабре, что это один из медленных способов. Там статья была, кто-то замерял. Правда, пару тройку свойств вывести в UI, думаю, никакой роли не сыграет вообще.
0
Эксперт .NET
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
21.04.2015, 18:58 9
Есть библиотечка PropertyChanged.Fody — она реализует интерфейс за вас, но делает это на стадии компиляции, то есть нет лишней нагрузки на рантайм.

Пример из документации:
Вы пишете:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
[ImplementPropertyChanged]
public class Person 
{        
    public string GivenNames { get; set; }
    public string FamilyName { get; set; }
 
    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }
}
Компилятор генериурет:
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
public class Person : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
 
    string givenNames;
    public string GivenNames
    {
        get { return givenNames; }
        set
        {
            if (value != givenNames)
            {
                givenNames = value;
                OnPropertyChanged("GivenNames");
                OnPropertyChanged("FullName");
            }
        }
    }
 
    string familyName;
    public string FamilyName
    {
        get { return familyName; }
        set 
        {
            if (value != familyName)
            {
                familyName = value;
                OnPropertyChanged("FamilyName");
                OnPropertyChanged("FullName");
            }
        }
    }
 
    public string FullName
    {
        get
        {
            return string.Format("{0} {1}", GivenNames, FamilyName);
        }
    }
 
    public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
2
Shamil1
21.04.2015, 21:31
  #10

Не по теме:

Цитата Сообщение от kolorotur Посмотреть сообщение
Есть библиотечка PropertyChanged.Fody — она реализует интерфейс за вас, но делает это на стадии компиляции, то есть нет лишней нагрузки на рантайм.
А какой принцип лежит в основе? Как можно поменять код на этапе компиляции?

0
Эксперт .NET
17688 / 12873 / 3366
Регистрация: 17.09.2011
Сообщений: 21,138
21.04.2015, 22:27 11
Цитата Сообщение от Shamil1 Посмотреть сообщение
А какой принцип лежит в основе? Как можно поменять код на этапе компиляции?
Не знаю, не интересовался.
Проект опенсорсный — почитайте код, там все есть.
0
21.04.2015, 22:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.04.2015, 22:27
Помогаю со студенческими работами здесь

Что бы реально начать программировать на Django есть один способ
В 2009 году? начиная изучать python, опросил около 200 человек программистов, как начать реально...

Выбор паяльника или остаться на том что есть?
Стоит ли покупать новый паяльник по скольку у меня дома лежит 2 паяльника ЭПСН далекого 1978 года...

Посоветуйте способ автоматического определения локации пользователя.
посоветуйте какой нибудь сервис, типа яндекс-карт, чтобы можно было определить местоположение...

Есть ли способ узнать, что данные отправляются без нашего ведома?
Здравствуйте, можете подсказать, есть ли способ на C# (может на каком еще языке, неважно) узнать,...

Условие в том, что символы в P1 и P2 должны быть в том же порядке, что и в S
создать программу, которая проверяет, можно ли сформировать заданную строку S из двух других строк:...


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

Или воспользуйтесь поиском по форуму:
11
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru