|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Custom Collection Editor - how to block the up and down buttons ?I have a Custom Collection Editor and overridden some methods - everything
works fine... BUT I now want to block the up and down buttons, so the User won't be able to move the Collection Items within the Index. Is there any possibilty by overriding a method so it won't move the collection items? To make it clear - I do not want to remove the buttons or make them invisible, I just want to block the functionality. Thank you in advance, Robert. Hi Robert,
I have spent several hours researching on this problem. Unfortunately, I haven't found any property or overridable method in CollectionEditor class to disable the up and down buttons in the collection editor dialog. I have tried to override the EditValue method. In the overridden EditValue method, the line of code 'base.EditValue(context, provider, value);' displays the collection editor dialog. But it's hard to get the dialog. And even if we could get the dialog, it might be impossible to disable the up and down button in the dialog, for the dialog may not expose such a property or method to allow us to do it. Coud you tell me why you want to disable the up and down buttons in the collection dialog? In my opinion, this function is very convenience for the user. I will go on researching on this issue and as soon as I have a new finding, I will get it back to you. Have a nice weekend! Sincerely, Linda Liu Microsoft Online Community Support ================================================== Get notification to my posts through email? Please refer to http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif ications. Note: The MSDN Managed Newsgroup support offering is for non-urgent issues where an initial response from the community or a Microsoft Support Engineer within 1 business day is acceptable. Please note that each follow up response may take approximately 2 business days as the support professional working with you may need further investigation to reach the most efficient resolution. The offering is not appropriate for situations that require urgent, real-time or phone-based interactions or complex project analysis and dump analysis issues. Issues of this nature are best handled working with a dedicated Microsoft Support Engineer by contacting Microsoft Customer Support Services (CSS) at http://msdn.microsoft.com/subscriptions/support/default.aspx. ================================================== This posting is provided "AS IS" with no warranties, and confers no rights. Hi Linda!
I have one Collection, which holds 'Distances' (in meters - declared as float), but it's vital that it has some kind of sort order. I have already (successfully) done some tricks to keep these values in order, even if the user adds new values via dialog 'add' button ;) ... - with 'in order' I mean the index of the Collection, i.e. index[0] 100 / index[1] 200 / index[2] 500, so if one adds a new value of 300, the collection will look like this: index[0] 100 / index[1] 200 / index[2] 300 / index[3] 500... If the 'add' button is pushed the newly added distance will be set to a value of 100(m) greater than the last element in the collection shows and if someone sets a new value the collection is resorted automatically ;) ... This is done by some (ugly ;) ) code within the Set Accessor like this: /// <summary> /// lod_distance of lod_distances. /// </summary> [Bindable(false), Category("Excelsior - Data"), Description("lod_distance of lod_distances.")] public float lod_distance { get { return this.m_lod_distance; } set { if (value <= 0) return; this.m_lod_distance = value; // mighty nasty Hack, but I **REALLY** LOVE IT ;) if (Convert.ToBoolean(Excelsior.Win32specific.Win32Registry.ReadObjectFromRegistry(Excelsior.Win32specific.ExcelsiorProjectIdentifier.EPI_TOOLSET, "ReorgFlag"))) return; Excelsior.Win32specific.Win32Registry.WriteObjectToRegistry(Excelsior.Win32specific.ExcelsiorProjectIdentifier.EPI_TOOLSET, "ReorgFlag", 1); float[] sortDistances = new float[((Material)this.Parent).lod_distances.Count]; for (int i = 0; i < ((Material)this.Parent).lod_distances.Count; i++) { sortDistances[i] = ((Material)this.Parent).lod_distances[i].lod_distance; } Array.Sort(sortDistances); for (int i = 0; i < ((Material)this.Parent).lod_distances.Count; i++) { ((Material)this.Parent).lod_distances[i].lod_distance = sortDistances[i]; } Excelsior.Win32specific.Win32Registry.WriteObjectToRegistry(Excelsior.Win32specific.ExcelsiorProjectIdentifier.EPI_TOOLSET, "ReorgFlag", 0); } } This is possible because the Collection is a property of another class and holds a refernce to the parent object - was really hard to get the Parent object set if an item is added via Collection Editor 'add'-Button, but I got this up and running ;) using this Code: /// <summary> /// override CreateInstance to implement our wanted behavior, /// setting a Reference to the Parent (Material) object, /// which holds the LoD_Distance Collection. /// </summary> protected override object CreateInstance(Type ItemType) { LoD_Distance lod = (LoD_Distance)base.CreateInstance(ItemType); if (this.Context.Instance != null) { if (this.Context.Instance is Material) { lod.SetParentObject((Material)this.Context.Instance); float[] sortDistances = new float[((Material)this.Context.Instance).lod_distances.Count]; for (int i = 0; i < ((Material)this.Context.Instance).lod_distances.Count; i++) { sortDistances[i] = ((Material)this.Context.Instance).lod_distances[i].lod_distance; System.Diagnostics.Debug.WriteLine(sortDistances[i].ToString()); } Array.Sort(sortDistances); if (sortDistances.Length >= 1) lod.lod_distance = sortDistances[sortDistances.Length - 1] + 100; else lod.lod_distance = 100; } } return lod; } So everythings work fine, until the User moves the Collection Items via the up/down Buttons, so I just want to get notified if this 'event' happens, so I can resort my Collection again, as I did in the Code above. Actually it is not necessary to 'block' the buttons, I am searching for a way to get notified that one of the buttons has been pushed, so I can re-sort my Collection Items to get this undone... Thank you for your help! Robert Show quote "Linda Liu [MSFT]" wrote: > Hi Robert, > > I have spent several hours researching on this problem. Unfortunately, I > haven't found any property or overridable method in CollectionEditor class > to disable the up and down buttons in the collection editor dialog. > > I have tried to override the EditValue method. In the overridden EditValue > method, the line of code 'base.EditValue(context, provider, value);' > displays the collection editor dialog. But it's hard to get the dialog. And > even if we could get the dialog, it might be impossible to disable the up > and down button in the dialog, for the dialog may not expose such a > property or method to allow us to do it. > > Coud you tell me why you want to disable the up and down buttons in the > collection dialog? In my opinion, this function is very convenience for the > user. > > I will go on researching on this issue and as soon as I have a new finding, > I will get it back to you. > > Have a nice weekend! > > > Sincerely, > Linda Liu > Microsoft Online Community Support > > ================================================== > Get notification to my posts through email? Please refer to > http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif > ications. > > Note: The MSDN Managed Newsgroup support offering is for non-urgent issues > where an initial response from the community or a Microsoft Support > Engineer within 1 business day is acceptable. Please note that each follow > up response may take approximately 2 business days as the support > professional working with you may need further investigation to reach the > most efficient resolution. The offering is not appropriate for situations > that require urgent, real-time or phone-based interactions or complex > project analysis and dump analysis issues. Issues of this nature are best > handled working with a dedicated Microsoft Support Engineer by contacting > Microsoft Customer Support Services (CSS) at > http://msdn.microsoft.com/subscriptions/support/default.aspx. > ================================================== > > This posting is provided "AS IS" with no warranties, and confers no rights. > > Hi Robert,
Thank you for your detailed explaination. I understand why you want to block the up and down buttons in the collection editor dialog now. To get notified when one of the up and down buttons is pushed, we would have two possible ways. One is to handle some event of the collection editor dialog and the other is to handle some event of the collection. As for the first 'option', we couldn't even get the collection editor dialog. Say nothing of handling some event of the editor dialog. As for the second 'option', I don't know which type the collection is in your project. The type of the collection in my test project is List<T>, which hasn't even one event. So it seems that the two possible candidates aren't feasible. In fact, since CollectionEditor is inherited from UITypeEditor and implement the EditValue method to popup the collection editor dialog and return the collection, we could override the EditValue method and re-sort the collection after the collection editor dialog is closed. The following is a sample of overriding the EditValue method. public class MyCollectionEditor:CollectionEditor { public MyCollectionEditor(Type type):base(type) { } public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value) { object ins = base.EditValue(context, provider, value); if (context.Instance != null) { if (context.Instance is Material) { // add your code to re-sort the collection in the Material object, e.g ((Material)context.Instance).SortList(); } } return ins; } } Since we need to re-sort the collection out of the LoD_Distance class, I recommend you to add a method in the Material class to re-sort the collection in it. And make some small modifications in the LoD_Distance class. The following is a sample. using System.Collections.Generic; using System.Drawing.Design; using System.ComponentModel; class Material { private List<LoD_Distance> lists = new List<LoD_Distance>(); [Editor(typeof(MyCollectionEditor),typeof(UITypeEditor))] public List<LoD_Distance> lod_distances { get { return lists; } } public Material() { } public void SortList() { float[] sortDistances = new float[this.lod_distances.Count]; for (int i = 0; i < this.lod_distances.Count; i++) { sortDistances[i] = this.lod_distances[i].lod_distance; } Array.Sort(sortDistances); for (int i = 0; i < this.lod_distances.Count; i++) { this.lod_distances[i].needsorting = false; this.lod_distances[i].lod_distance = sortDistances[i]; this.lod_distances[i].needsorting = true; } } } class LoD_Distance { public bool needsorting = true; [Bindable(false),Category("Excelsior - Data"),Description("lod_distance of lod_distances.")] public float lod_distance { get { return this.m_lod_distance; } set { if (value <= 0) return; this.m_lod_distance = value; if (needsorting == true) { this.parent.SortList(); } } } private float m_lod_distance=0; private Material parent = null; public Material Parent { get { return parent; } } public void SetParentObject(Material obj) { parent = obj; } } Hope this helps. If you have anything unclear, please feel free to let me know. Sincerely, Linda Liu Microsoft Online Community Support Hi Linda and Robert,
1. About second option Linda mentioned, maybe one could use System.Collections.CollectionBase as base class for collection in question. This class provides protected virtual events like OnInsert, OnRemove, OnClear. 2) According to http://www.codeproject.com/csharp/DzCollectionEditor.asp CollectionEditor works with IList, so one could implement a class that implements IList and trace how CollectionEditor move items up or down. By knowing this implementation can be changed to prevent moving of items up or down. Hope it helps. Petar Repac Hi Linda, hi Peter!
First I want to thank Linda for her information, helped me a lot... I think overriding the EditValue Method will be my favorite solution - it's really ok to start sorting on closing the Editor... > 1. About second option Linda mentioned, I am already deriving my Collection from CollectionBase, nice to know that > maybe one could use System.Collections.CollectionBase as > base class for collection in question. > This class provides protected virtual events like OnInsert, OnRemove, > OnClear. there are events which can be used - I 'll look into this soon... - thank you, Peter! > 2) According to Sounds not easy - I have already looked at Collection Editor's code, but > http://www.codeproject.com/csharp/DzCollectionEditor.asp > CollectionEditor works with IList, so one could implement a class that > implements IList and trace how CollectionEditor move items up or down. > By knowing this implementation can be changed to prevent moving of items > up or down. it's not easy to understand - I must admit that I would have coded Collection Editor much simpler than MS did ;) - but I am far away from writing such complex things like .NET Framework - so I think your second suggestion is too time consuming to implement - at least for me ;) ! Thank you Linda, thank you Peter! Robert |
|||||||||||||||||||||||