To illustrate the problem domain, let's say we have a enum called MartType as follows.
public enum MartType{ Safeway, QFC, Alberson, HMart }
If we display a enum type property in PropertyGrid (actually I used WPF property grid which is included in WPF extended toolkit), it will show a combox editor containing all enum values.
Now, what if we want to display a subset of enum values based on Area? For example, in case of another city (Bellevue), we only want to show 3 grocery stores.
In order to do this, one should restrict ItemsSource data for the ComboBox. And in order to accomplish this in WPF PropertyGrid control, one have to add a special editor to handle this special case (will write about this later).
For the example above, let's say we expose 2 properties like this.
public string Area { get; set; } public EnumFilter<MartType>AreaMartType { get; set; }
AreaMartType public property is not simply MartType enum, but a EnumFilter of MartType. This AreaMartType is set by the following helper private method, which returns filtered enum based on areaNo.
private EnumFilter<MartType>FilterMarts(int areaNo, MartType selectedMart) { List subset = new List (); switch (areaNo) { case 1: subset.Add(MartType.QFC); subset.Add(MartType.Alberson); subset.Add(MartType.HMart); break; case 2: subset.Add(MartType.QFC); subset.Add(MartType.Alberson); subset.Add(MartType.Safeway); break; case 3: subset.Add(MartType.Alberson); subset.Add(MartType.Safeway); subset.Add(MartType.HMart); break; default: subset.Add(MartType.QFC); subset.Add(MartType.Alberson); subset.Add(MartType.Safeway); subset.Add(MartType.HMart); break; } EnumFilter<MartType> enumFilter = new EnumFilter<MartType> (subset); enumFilter.Value = selectedMart; return enumFilter; }
So EnumFilter of T class takes enum value list which is a subset of enum values. And GetEnums() method actually do the filtering work based on the given subset. By IEnumerable and yield only filtered one, it can dynamically retrieve a subset of enum items.
public class EnumFilter { } public class EnumFilter<T>: EnumFilter, INotifyPropertyChanged where T : struct { private List _elements; private T _value; public EnumFilter() { _elements = new List<T> (); } public EnumFilter(List<T> elements) { _elements = elements; } public IEnumerable<T> GetEnums() { foreach (var field in typeof(T).GetFields( BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static)) { T enumVal = (T)field.GetValue(null); if (_elements.Contains(enumVal)) { yield return enumVal; } } } public T Value { get { return _value; } set { _value = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("Value")); } } } public event PropertyChangedEventHandler PropertyChanged; }
How we display the subset of enums in WPF PropertyGrid is little different topic but related. Will write more. (Please see : http://dotnetbeyond.blogspot.com/2012/08/wpf-propertygrid-display-partial-enum.html )
Hi Alex, I would like to see your example in source code for this article. Thank you for you help.
ReplyDeleteTan Le, I am not sure what you mean, but if you want to see how to display filtered enum subset, please refer to this link : http://dotnetbeyond.blogspot.com/2012/08/wpf-propertygrid-display-partial-enum.html
ReplyDeleteThanks for your replying. But I mean can you give me current source code of this example.
DeleteTan Le - The post is 1 yr old. I am afraid that I cannot find the source code... Sorry.
DeleteMany thanks :)
ReplyDelete