Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Parameters/3.3/OptionalConstrainedValueParameter.cs @ 3496

Last change on this file since 3496 was 3341, checked in by swagner, 15 years ago

Implemented reviewers' comments (#893).

File size: 7.0 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) 2002-2010 Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Drawing;
24using HeuristicLab.Collections;
25using HeuristicLab.Common;
26using HeuristicLab.Core;
27using HeuristicLab.Persistence.Default.CompositeSerializers.Storable;
28
29namespace HeuristicLab.Parameters {
30  /// <summary>
31  /// A parameter whose value has to be chosen from a set of valid values or is null.
32  /// </summary>
33  [Item("OptionalConstrainedValueParameter<T>", "A parameter whose value has to be chosen from a set of valid values or is null.")]
34  [StorableClass]
35  public class OptionalConstrainedValueParameter<T> : Parameter, IValueParameter<T> where T : class, IItem {
36    public override Image ItemImage {
37      get {
38        if (value != null) return value.ItemImage;
39        else return base.ItemImage;
40      }
41    }
42
43    [Storable]
44    private ItemSet<T> validValues;
45    public ItemSet<T> ValidValues {
46      get { return validValues; }
47    }
48
49    [Storable]
50    private T value;
51    public virtual T Value {
52      get { return this.value; }
53      set {
54        if (value != this.value) {
55          if ((value != null) && !validValues.Contains(value)) throw new ArgumentException("Invalid value.");
56          DeregisterValueEvents();
57          this.value = value;
58          RegisterValueEvents();
59          OnValueChanged();
60        }
61      }
62    }
63
64    IItem IValueParameter.Value {
65      get { return Value; }
66      set {
67        T val = value as T;
68        if ((value != null) && (val == null))
69          throw new InvalidOperationException(
70            string.Format("Type mismatch. Value is not a \"{0}\".",
71                          typeof(T).GetPrettyName())
72          );
73        Value = val;
74      }
75    }
76
77    public OptionalConstrainedValueParameter()
78      : base("Anonymous", typeof(T)) {
79      this.validValues = new ItemSet<T>();
80      Initialize();
81    }
82    public OptionalConstrainedValueParameter(string name)
83      : base(name, typeof(T)) {
84      this.validValues = new ItemSet<T>();
85      Initialize();
86    }
87    public OptionalConstrainedValueParameter(string name, ItemSet<T> validValues)
88      : base(name, typeof(T)) {
89      this.validValues = validValues;
90      Initialize();
91    }
92    public OptionalConstrainedValueParameter(string name, ItemSet<T> validValues, T value)
93      : base(name, typeof(T)) {
94      this.validValues = validValues;
95      this.value = value;
96      Initialize();
97    }
98    public OptionalConstrainedValueParameter(string name, string description)
99      : base(name, description, typeof(T)) {
100      this.validValues = new ItemSet<T>();
101      Initialize();
102    }
103    public OptionalConstrainedValueParameter(string name, string description, ItemSet<T> validValues)
104      : base(name, description, typeof(T)) {
105      this.validValues = validValues;
106      Initialize();
107    }
108    public OptionalConstrainedValueParameter(string name, string description, ItemSet<T> validValues, T value)
109      : base(name, description, typeof(T)) {
110      this.validValues = validValues;
111      this.value = value;
112      Initialize();
113    }
114    [StorableConstructor]
115    protected OptionalConstrainedValueParameter(bool deserializing) : base(deserializing) { }
116
117    [StorableHook(HookType.AfterDeserialization)]
118    private void Initialize() {
119      RegisterValidValuesEvents();
120      RegisterValueEvents();
121    }
122
123    public override IDeepCloneable Clone(Cloner cloner) {
124      OptionalConstrainedValueParameter<T> clone = (OptionalConstrainedValueParameter<T>)base.Clone(cloner);
125      clone.validValues = (ItemSet<T>)cloner.Clone(validValues);
126      clone.value = (T)cloner.Clone(value);
127      clone.Initialize();
128      return clone;
129    }
130
131    public override string ToString() {
132      return string.Format("{0}: {1} ({2})", Name, Value != null ? Value.ToString() : "null", DataType.GetPrettyName());
133    }
134
135    protected override IItem GetActualValue() {
136      return Value;
137    }
138    protected override void SetActualValue(IItem value) {
139      ((IValueParameter)this).Value = value;
140    }
141
142    public event EventHandler ValueChanged;
143    protected virtual void OnValueChanged() {
144      if (ValueChanged != null)
145        ValueChanged(this, EventArgs.Empty);
146      OnItemImageChanged();
147      OnToStringChanged();
148    }
149
150    private void RegisterValidValuesEvents() {
151      if (validValues != null) {
152        validValues.ItemsAdded += new CollectionItemsChangedEventHandler<T>(ValidValues_ItemsAdded);
153        validValues.ItemsRemoved += new CollectionItemsChangedEventHandler<T>(ValidValues_ItemsRemoved);
154        validValues.CollectionReset += new CollectionItemsChangedEventHandler<T>(ValidValues_CollectionReset);
155      }
156    }
157    private void DeregisterValidValuesEvents() {
158      if (validValues != null) {
159        validValues.ItemsAdded -= new CollectionItemsChangedEventHandler<T>(ValidValues_ItemsAdded);
160        validValues.ItemsRemoved -= new CollectionItemsChangedEventHandler<T>(ValidValues_ItemsRemoved);
161        validValues.CollectionReset -= new CollectionItemsChangedEventHandler<T>(ValidValues_CollectionReset);
162      }
163    }
164    protected virtual void ValidValues_ItemsAdded(object sender, CollectionItemsChangedEventArgs<T> e) { }
165    protected virtual void ValidValues_ItemsRemoved(object sender, CollectionItemsChangedEventArgs<T> e) {
166      if ((Value != null) && !validValues.Contains(Value)) Value = null;
167    }
168    protected virtual void ValidValues_CollectionReset(object sender, CollectionItemsChangedEventArgs<T> e) {
169      if ((Value != null) && !validValues.Contains(Value)) Value = null;
170    }
171
172    private void RegisterValueEvents() {
173      if (value != null) {
174        value.ItemImageChanged += new EventHandler(Value_ItemImageChanged);
175        value.ToStringChanged += new EventHandler(Value_ToStringChanged);
176      }
177    }
178    private void DeregisterValueEvents() {
179      if (value != null) {
180        value.ItemImageChanged -= new EventHandler(Value_ItemImageChanged);
181        value.ToStringChanged -= new EventHandler(Value_ToStringChanged);
182      }
183    }
184    private void Value_ItemImageChanged(object sender, EventArgs e) {
185      OnItemImageChanged();
186    }
187    private void Value_ToStringChanged(object sender, EventArgs e) {
188      OnToStringChanged();
189    }
190  }
191}
Note: See TracBrowser for help on using the repository browser.