Исходный код вики Change notify
Версия 1.1 от Alexandr Fokin на 2024/08/17 13:14
Последние авторы
author | version | line-number | content |
---|---|---|---|
1 | |(% style="width:81px" %) |(% style="width:1356px" %) | ||
2 | |(% style="width:81px" %) |(% style="width:1356px" %)((( | ||
3 | |{{code language="c#"}}/// <summary> | ||
4 | /// Контейнер с INotifyPropertyChanged | ||
5 | /// </summary> | ||
6 | public class ObservableContainer<T> | ||
7 | : INotifyPropertyChanged, | ||
8 | IEquatable<ObservableContainer<T>>, | ||
9 | IEquatable<T> | ||
10 | { | ||
11 | #region prop | ||
12 | |||
13 | private T _data; | ||
14 | |||
15 | public event PropertyChangedEventHandler PropertyChanged; | ||
16 | |||
17 | public T Data | ||
18 | { | ||
19 | get => _data; | ||
20 | set | ||
21 | { | ||
22 | _data = value; | ||
23 | PropertyChanged?.Invoke( | ||
24 | this, | ||
25 | new PropertyChangedEventArgs(nameof(Data)) | ||
26 | ); | ||
27 | } | ||
28 | } | ||
29 | |||
30 | #endregion | ||
31 | |||
32 | |||
33 | #region ctor | ||
34 | |||
35 | public ObservableContainer() { } | ||
36 | public ObservableContainer(T data) | ||
37 | { | ||
38 | _data = data; | ||
39 | } | ||
40 | |||
41 | #endregion | ||
42 | |||
43 | |||
44 | #region override | ||
45 | |||
46 | public override string ToString() | ||
47 | { | ||
48 | return _data?.ToString() ?? "null"; | ||
49 | } | ||
50 | |||
51 | public override int GetHashCode() | ||
52 | { | ||
53 | return _data?.GetHashCode() ?? 0; | ||
54 | } | ||
55 | |||
56 | public override bool Equals(object obj) | ||
57 | { | ||
58 | if (obj is ObservableContainer<T> o1) | ||
59 | { | ||
60 | return Equals(other: o1); | ||
61 | } | ||
62 | else if (obj is T o2) | ||
63 | { | ||
64 | return Equals(other: o2); | ||
65 | } | ||
66 | |||
67 | return false; | ||
68 | } | ||
69 | |||
70 | public bool Equals(ObservableContainer<T> other) | ||
71 | { | ||
72 | if (other.Data == null && Data == null) | ||
73 | { | ||
74 | return true; | ||
75 | } | ||
76 | if (other.Data != null) | ||
77 | { | ||
78 | other.Data.Equals(Data); | ||
79 | } | ||
80 | if (Data != null) | ||
81 | { | ||
82 | Data.Equals(other.Data); | ||
83 | } | ||
84 | |||
85 | return false; | ||
86 | } | ||
87 | |||
88 | public bool Equals(T other) | ||
89 | { | ||
90 | if (other == null && Data == null) | ||
91 | { | ||
92 | return true; | ||
93 | } | ||
94 | if (other != null) | ||
95 | { | ||
96 | other.Equals(Data); | ||
97 | } | ||
98 | if (Data != null) | ||
99 | { | ||
100 | Data.Equals(other); | ||
101 | } | ||
102 | |||
103 | return false; | ||
104 | } | ||
105 | |||
106 | #endregion | ||
107 | |||
108 | #region operator | ||
109 | |||
110 | public static implicit operator ObservableContainer<T>(T x) | ||
111 | { | ||
112 | return new ObservableContainer<T>(x); | ||
113 | } | ||
114 | public static implicit operator T(ObservableContainer<T> x) | ||
115 | { | ||
116 | return x.Data; | ||
117 | } | ||
118 | |||
119 | #endregion | ||
120 | }{{/code}} | ||
121 | |{{code language="c#"}}public class TestModel2 | ||
122 | { | ||
123 | public ObservableContainer<string> Property1 { get; set; } | ||
124 | = new ObservableContainer<string>(); | ||
125 | public ObservableContainer<string> Property2 { get; set; } | ||
126 | = new ObservableContainer<string>(); | ||
127 | }{{/code}} | ||
128 | |{{code language="xml"}}<UniformGrid Rows="2" Columns="2"> | ||
129 | <TextBox Text="Prop1"></TextBox> | ||
130 | <TextBox Text="{Binding Path=Property1.Data, Mode=OneWay}"></TextBox> | ||
131 | <Button Content="Right Bottom" /> | ||
132 | |||
133 | <TextBox Text="Prop2"></TextBox> | ||
134 | <TextBox Text="{Binding Path=Property2.Data, Mode=TwoWay}"></TextBox> | ||
135 | <Button Content="Right Bottom" Click="Button_Click" /> | ||
136 | </UniformGrid>{{/code}} | ||
137 | ))) | ||
138 | |(% style="width:81px" %) |(% style="width:1356px" %) | ||
139 | |||
140 |