Solved

StringCollection Set Property Not Firing Correctly

Posted on 2010-08-12
11
554 Views
Last Modified: 2013-12-17
private System.Collections.Specialized.StringCollection _Names;
        [Editor("System.Windows.Forms.Design.StringCollectionEditor,System.Design,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StringCollection Names
        {
            get
            {
                return _Names;
            }
            set
            {
                _Names = value;
                foreach (string Name in _Names)
                {
                    System.Diagnostics.Debug.WriteLine("Table Control: Tag: " + Name);
                }
          }
        }

I could change the values inside the Names property via the property grid. But it does not print anything to the OUTPUT windows. What am I doing wrong here??
0
Comment
Question by:YetAnotherCoder
  • 5
  • 3
  • 3
11 Comments
 
LVL 16

Expert Comment

by:kris_per
Comment Utility

See what happens if you use 'MessageBox' instead of 'WriteLine'....
0
 

Author Comment

by:YetAnotherCoder
Comment Utility
The set property is not executing.....at all
0
 
LVL 3

Expert Comment

by:yanoch
Comment Utility
You should initiate the string collection before setting a value.

the set of the property is just fired if you add a new string collection to _Names.
     Names = new StringCollection(); // It fire the set

In your case, your are modifying the current string collection (Current value of _Names) and using the get of the property.
 
you should write your code like that :

 private System.Collections.Specialized.StringCollection _Names = new StringCollection();
        [Editor("System.Windows.Forms.Design.StringCollectionEditor,System.Design,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
        public StringCollection Names
        {
            get
            {
                 //fired when accessing the _Names value
                 //In your case when you modify it.
                return _Names;
            }
            set
            {
                //fired when setting the _Names  value

                _Names = value;
                foreach (string Name in _Names)
                {
                    System.Diagnostics.Debug.WriteLine("Table Control: Tag: " + Name);
                }
        }
0
 

Author Comment

by:YetAnotherCoder
Comment Utility
Hi Yanoch,
It is not firing when I modify the collection via the CollectionEditor in the design mode. Have you verified it??? What have you modified to my code.... I couldn't follow if you have made any changes other than the comments.....
0
 
LVL 3

Expert Comment

by:yanoch
Comment Utility
added
private System.Collections.Specialized.StringCollection _Names = new StringCollection();

No it is not fireing because you are only modifying the current instance of _Names, you are not adding a new value to it.

if you do : _Names = something it will fire the set.

In your case the property editor modify the content of _Names it does not set a someting to _Names.

The property editor does not create a new instance of _Names, it is only modifying it.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:YetAnotherCoder
Comment Utility
Is there a work around for this?? or a better way to do this... Please need some help
0
 
LVL 16

Expert Comment

by:kris_per
Comment Utility

@YetAnotherCoder

As yanoch has posted, set property is not executed because it is not called or not used by the designer at all...

When you add items to the Names property in the designer editor, it adds the new items to the already existing Names list (like Names.Add) and it is not setting any new value to Names property. i.e. Names set is not called at all...

Names set will be called when you do something like below:

public Form1()
{
        InitializeComponent();

        myControl.Names = new new System.Collections.Specialized.StringCollection(); // Now Names set will be called

         myControl.Names.Add("item1"); // Here Names set will not be called. Designer/Editor is doing this..

}

So i think you dont need any workaround...that's the way it is....hope this helps...


0
 

Author Comment

by:YetAnotherCoder
Comment Utility
Hey Kris,

But I using the above mentioned property in a UserControl where users would like to make changes in the PropertyGrid. They wont have access to the code.... Similar to Comobo Box Items Collection, I would like to provide my control a Names property that lets them make changes to the list as they wish..... As they make changes in the designer, I would like to know so that I could update other properties that depend on Names Collection property.

So how could I get changes notifications when made to this property in the designer itself?? Or is there a workaround for this??

Thank You
0
 
LVL 3

Accepted Solution

by:
yanoch earned 250 total points
Comment Utility
If you want to have an event when the property is changin you have to write your own collection class

here's an example.

You have all the events needed

using System;

using System.Collections;

using System.Collections.Generic;



namespace SmartControls.Types

{

    public class ItemChangedArgs<T> : EventArgs

    {

        public int Index { get; set; }

        public T Item { get; set; }

    }



    public class EventList<T> : CollectionBase

    {

        public event EventHandler<ItemChangedArgs<T>> ItemAdded;

        public event EventHandler<ItemChangedArgs<T>> ItemRemoved;

        public event EventHandler<ItemChangedArgs<T>> ItemChanged;

        public event EventHandler Cleared;



        public void Add(T item)

        {

            this.List.Add(item);

        }



        public void AddRange(IEnumerable<T> collection)

        {

            foreach (T t in collection)

            {

                this.List.Add(t);

            }

        }



        private void OnItemAdded(int index, T item)

        {

            if (ItemAdded != null)

                ItemAdded(this, new ItemChangedArgs<T> { Index = index, Item = item });

        }



        public int IndexOf(T item)

        {

            return this.List.IndexOf(item);

        }



        public void Insert(int index, T item)

        {

            this.List.Insert(index, item);

            OnItemAdded(index, item);

        }



        protected override void OnRemoveComplete(int index, object value)

        {

            OnRemove(index, (T)value);

            base.OnRemoveComplete(index, value);

        }



        protected override void OnClearComplete()

        {

            OnCleared();

            base.OnClearComplete();

        }



        protected override void OnSetComplete(int index, object oldValue, object newValue)

        {

            OnItemChanged(index, (T)newValue);

            base.OnSetComplete(index, oldValue, newValue);

        }



        protected override void OnInsertComplete(int index, object value)

        {

            OnItemAdded(index, (T)value);

            base.OnInsertComplete(index, value);

        }

        

        private void OnItemRemoved(int index, T item)

        {

            if (ItemRemoved != null)

                ItemRemoved(this, new ItemChangedArgs<T> { Index = index, Item = item });

        }



        public T this[int index]

        {

            get 

            {

                return (T)this.List[index]; 

            }

            set

            {

                this.List[index] = value;

                OnItemChanged(index, (T)this.List[index]);

            }

        }



        private void OnItemChanged(int index, T item)

        {

            if (ItemChanged != null)

                ItemChanged(this, new ItemChangedArgs<T> { Index = index, Item = item });

        }



        private void OnCleared()

        {

            if (Cleared != null) 

                Cleared(this, null);

        }



        public bool Contains(T item)

        {

            return this.List.Contains(item);

        }



        public void CopyTo(T[] array, int arrayIndex)

        {

            this.List.CopyTo(array, arrayIndex);

        }



        public void Remove(T item)

        {

            this.List.Remove(item);

        }

    } 



}

Open in new window

0
 
LVL 16

Assisted Solution

by:kris_per
kris_per earned 250 total points
Comment Utility

I have tired yanoch's code. It is working good and hope that's what you want...you have to use it like as shown below:
public partial class UserControl5 : UserControl

    {

        public UserControl5()

        {

            InitializeComponent();



            _Names.ItemAdded += new EventHandler<ItemChangedArgs<string>>(_Names_ItemAdded);

        }



        void _Names_ItemAdded(object sender, ItemChangedArgs<string> e)

        {

            // this method will be called whenever item is added to _Names

        }



        private EventList<string> _Names = new EventList<string>();



        [Editor("System.Windows.Forms.Design.StringCollectionEditor,System.Design,Version=2.0.0.0,Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a", typeof(System.Drawing.Design.UITypeEditor))]

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]

        public EventList<string> Names

        {

            get

            {

                 //fired when accessing the _Names value 

                 //In your case when you modify it.

                return _Names;

            }

            set

            {

                //fired when setting the _Names  value



                _Names = value;

                foreach (string Name in _Names)

                {

                    System.Diagnostics.Debug.WriteLine("Table Control: Tag: " + Name);

                }

            }

        }

}

Open in new window

0
 

Author Closing Comment

by:YetAnotherCoder
Comment Utility
Thank you Yanoch the class and Kris_per for showing the usage... Apreciate both your help......Very nice.....
0

Featured Post

What Security Threats Are You Missing?

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

Join & Write a Comment

In my previous article (http://www.experts-exchange.com/Programming/Languages/.NET/.NET_Framework_3.x/A_4362-Serialization-in-NET-1.html) we saw the basics of serialization and how types/objects can be serialized to Binary format. In this blog we wi…
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Excel styles will make formatting consistent and let you apply and change formatting faster. In this tutorial, you'll learn how to use Excel's built-in styles, how to modify styles, and how to create your own. You'll also learn how to use your custo…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now