2

I need to control whenever the struct or object property is changed. It does not have any event that I can use.

Sample: How can I know when the Width or Height is changed? Is that even possible?

"System.Drawing.Size = Size"

    private Size mySize;

    public Size MySize
    {
        get {
            //What if X or Y is changed?? I need to know that
            return mySize; 
        }
        set {

            mySize = value; 
        }
    }

For this specific case, if Size properties were read only the problem would be solved. But they are not.

Pedro77
  • 5,176
  • 7
  • 61
  • 91

4 Answers4

4

Edit in response to comments:

Sample: How can I know when the Width or Height is changed? Is that even possible?

No, this is not possible. However, it doesn't matter.

When you return a Size from your class, since Size is a struct, you're returning a copy. Even if the user changes the Width or Height of the Size you return, it has no impact on the mySize struct in your class.

In order to change your Size, they need to change the entire thing, ie:

var temp = yourClass.MySize;
temp.Width = newWidth;
yourClass.MySize = temp; // The user will need to assign an entire Size

As far as you should be concerned, the Size properties are effectively read only, since System.Drawing.Size is a value type.


Original answer, given the assumption that Width and Height were properties of the user's class:

There are two main options -

You can compute the size on the fly, instead of storing it, based on your Width and Height:

public Size MySize
{
    get {            
        return new Size(Width,Height); 
    }
    set {
        Width = value.Width; 
        Height = value.Height; // Set Width/Height appropriately
    }
}

Another option is to recompute your size in your property setter for Width and Height:

public double Width
{
   get { return width; }
   set
   {
         width = value;
         mySize = new Size(width, Height); // Compute new size, so it's always correct
   }
}

Finally, if you're using something like INotifyPropertyChanged to track changes, you could also subscribe to your own PropertyChanged event, and if it's the appropriate property, recompute your size.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • If someone changes Width or Height my class will not be aware of it. This is the problem. – Pedro77 Jul 16 '13 at 16:52
  • @Pedro77 Is Width and Height part of your class, too? If so, just make them properties, and the only way they'd change it is with you being aware of it... – Reed Copsey Jul 16 '13 at 16:56
  • No, they are part of the .NET Size structure. – Pedro77 Jul 16 '13 at 16:57
  • 1
    @Pedro77 The user can't set Width and Height directly on your size - Size is a structure, which means that your property returns a *copy* - so there's no way they can ever change the Width and Height. – Reed Copsey Jul 16 '13 at 16:59
3

Short answer - no, there is no events on plain old C# objects that are fired when field changes.

Your options I know of:

  • change your class (if you can) to fire events
  • inherit from your class and write event firing code in derived class (assuming virtual get/set are possible)
  • extract properties into an interface, use that interface throughout code and build wrapper for generic interface that fires property changes.

Note that mutable struct considered evil - try to avoid "whenever the struct property is changed" case altogether.

Community
  • 1
  • 1
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
  • The solution would be to make a new Size class, like "class MySize" that implements events on property changed. Its not possible to use the old Size structure because Width or Height can be changed outside my class. I was hopping there was a workaround to that problem. – Pedro77 Jul 16 '13 at 16:56
1

Edit After realizing it is a Struct:

Consider Eric Lippert's wonderful article in his blog about Mutable Structs Mutating Readonly Structs(Evil)

Take a look at INotifyPropertyChanged Interface

and INotifyPropertyChanging Interface

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • Yeah I know that. But Size is a struct and it does not implement this interface. So if someone changes Width or Height my class will not be aware of it. – Pedro77 Jul 16 '13 at 16:50
  • Framework itself doesn't provide option like that, you have to implement one. – Sriram Sakthivel Jul 16 '13 at 17:01
1

You can create an event and raise it in appropriate Set method. Alternately you may check this link, has both examples:

Raise an event whenever a property's value changed?

Community
  • 1
  • 1
seshuk
  • 182
  • 4