[corlib] Update ValueTuple implementation
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Base / Core / PropertyEditing / propertyentry.cs
1 using System.Diagnostics.CodeAnalysis;
2
3 namespace System.Activities.Presentation.PropertyEditing
4 {
5     using System.ComponentModel;
6     using System.Collections;
7     using System;
8     using System.Diagnostics;
9     using System.Activities.Presentation;
10
11     /// <summary>
12     /// The PropertyEntry class provides additional, mostly type-specific data for a property.
13     /// </summary>
14     public abstract class PropertyEntry : INotifyPropertyChanged, IPropertyFilterTarget {
15
16         private PropertyValue _parentValue;
17         private bool _matchesFilter = true;
18         private PropertyValue _value;
19
20         /// <summary>
21         /// Creates a PropertyEntry.  For host infrastructure derived classes.
22         /// </summary>
23         protected PropertyEntry() : this(null) { }
24
25         /// <summary>
26         /// Creates a PropertyEntry that acts as a sub-property of the specified PropertyValue.
27         /// For host infrastructure derived classes.
28         /// </summary>
29         /// <param name="parentValue">The parent PropertyValue.
30         /// Root properties do not have a parent PropertyValue.</param>
31         protected PropertyEntry(PropertyValue parentValue) {
32             _parentValue = parentValue;
33         }
34
35         /// <summary>
36         /// Gets the name of the encapsulated property.
37         /// </summary>
38         public abstract string PropertyName { get; }
39
40         /// <summary>
41         /// Gets the DisplayName for the property. By default, it is the
42         /// PropertyName.
43         /// </summary>
44         public virtual string DisplayName { get { return this.PropertyName; } }
45
46         /// <summary>
47         /// Gets the Type of the encapsulated property.
48         /// </summary>
49         public abstract Type PropertyType { get; }
50
51         /// <summary>
52         /// Gets the name of the category that this property resides in.
53         /// </summary>
54         public abstract string CategoryName { get; }
55
56         /// <summary>
57         /// Gets the description of the encapsulated property.
58         /// </summary>
59         public abstract string Description { get; }
60
61         /// <summary>
62         /// Returns true if there are standard values for this property.
63         /// The default implementation checks if the StandardValues property
64         /// returns a non-null collection with a count > 0.
65         /// </summary>
66         protected virtual bool HasStandardValues {
67             get {
68                 ICollection values = StandardValues;
69                 return values != null && values.Count > 0;
70             }
71         }
72
73         /// <summary>
74         /// Accessor because we use this property in the property container.
75         /// </summary>
76         internal bool HasStandardValuesInternal {
77             get { return HasStandardValues; }
78         }
79
80         /// <summary>
81         /// Gets the read-only attribute of the encapsulated property.
82         /// </summary>
83         public abstract bool IsReadOnly { get; }
84
85         /// <summary>
86         /// Gets a flag indicating whether the encapsulated property is an advanced property.
87         /// </summary>
88         public abstract bool IsAdvanced { get; }
89
90         /// <summary>
91         /// Gets any StandardValues that the encapsulated property supports.
92         /// </summary>
93         public abstract ICollection StandardValues { get; }
94
95         /// <summary>
96         /// Gets to PropertyValueEditor to be used for editing of this PropertyEntry.
97         /// May be null.  PropertyContainer listens to changes made to this property.
98         /// If the value changes, it's the responsibility of the deriving class to fire the
99         /// appropriate PropertyChanged event.
100         /// </summary>
101         public abstract PropertyValueEditor PropertyValueEditor { get; }
102
103         /// <summary>
104         /// Gets the parent PropertyValue.  This is only used for sub-properties and,
105         /// hence, its balue may be null.
106         /// </summary>
107         public PropertyValue ParentValue {
108             get {
109                 return _parentValue;
110             }
111         }
112
113         /// <summary>
114         /// Gets the PropertyValue (data model) for this PropertyEntry.
115         /// </summary>
116         public PropertyValue PropertyValue {
117             get {
118                 if (_value == null)
119                     _value = CreatePropertyValueInstance();
120
121                 return _value;
122             }
123         }
124
125         /// <summary>
126         /// Used by the host infrastructure to create a new host-specific PropertyValue instance.
127         /// </summary>
128         /// <returns>new PropertyValue</returns>
129         protected abstract PropertyValue CreatePropertyValueInstance();
130
131         // IPropertyFilterTarget Members
132
133         /// <summary>
134         /// IPropertyFilterTarget event
135         /// </summary>
136         public event EventHandler<PropertyFilterAppliedEventArgs> FilterApplied;
137
138         /// <summary>
139         /// IPropertyFilterTarget method. PropertyContainer listens to changes made to this property.
140         /// </summary>
141         public bool MatchesFilter {
142             get {
143                 return _matchesFilter;
144             }
145             protected set {
146                 if (value != _matchesFilter) {
147                     _matchesFilter = value;
148                     OnPropertyChanged("MatchesFilter");
149                 }
150             }
151         }
152
153         /// <summary>
154         /// IPropertyFilterTarget method
155         /// </summary>
156         /// <param name="predicate">the predicate to match against</param>
157         /// <returns>true if there is a match</returns>
158         public virtual bool MatchesPredicate(PropertyFilterPredicate predicate) {
159             return predicate == null ?
160                 false :
161                 predicate.Match(this.DisplayName) || predicate.Match(this.PropertyType.Name);
162         }
163
164         /// <summary>
165         /// IPropertyFilterTarget method
166         /// </summary>
167         /// <param name="filter">the PropertyFilter to apply</param>
168         public virtual void ApplyFilter(PropertyFilter filter) {
169             this.MatchesFilter = filter == null ? true : filter.Match(this);
170             OnFilterApplied(filter);
171         }
172
173         /// <summary>
174         /// Used to raise the IPropertyFilterTarget FilterApplied event
175         /// </summary>
176         /// <param name="filter"></param>
177         protected virtual void OnFilterApplied(PropertyFilter filter) {
178             if (FilterApplied != null)
179                 FilterApplied(this, new PropertyFilterAppliedEventArgs(filter));
180         }
181
182
183         // INotifyPropertyChanged
184
185         /// <summary>
186         /// INotifyPropertyChanged event
187         /// </summary>
188         public event PropertyChangedEventHandler PropertyChanged;
189
190         /// <summary>
191         /// Used to raise the INotifyPropertyChanged PropertyChanged event
192         /// </summary>
193         /// <param name="e">EventArgs for this event</param>
194         protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) {
195             if (e == null)
196                 throw FxTrace.Exception.ArgumentNull("e");
197
198             if (this.PropertyChanged != null)
199                 this.PropertyChanged(this, e);
200         }
201
202         /// <summary>
203         /// Used to raise the INotifyPropertyChanged event
204         /// </summary>
205         /// <param name="propertyName"></param>
206         /// <exception cref="ArgumentNullException">When propertyName is null</exception>
207         protected virtual void OnPropertyChanged(string propertyName) {
208             if (propertyName == null)
209                 throw FxTrace.Exception.ArgumentNull("propertyName");
210
211             if (this.PropertyChanged != null)
212                 this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
213         }
214
215     }
216 }
217