Updating Height and Width

Since Silverlight V1.1 Alpha does not have layout functionality built in, control does not get notified when its size changes. This is very important because control might want to layout other elements that constitute the visuals for that control. It is something that could be solved in the user code with a simple pattern. The pattern that I talk about here in this entry is the same that is implemented in the sample control pack that are part of SDK package for Silverlight Alpha 1.1 that you can find here.

There few problems that need to be solved...

  1. Control base class has Height and Width property that are not virtual. That means the specific control that inherits from this base class either needs to call its own Height/Width something else (e.g. ButtonHeight and ButtonWidth) or it needs to have its own "new" implementation of those property.
  2. When the Height and Width changes, control needs to update its visual to match its own Height and Width.
  3. If parser finds the properties on the base class then it sets properties on base class that is part of the platform. That means, with the second approach, in custom control class, since FrameworkElement has Height and Width property parser sets those property and since properties are not virtual they don't show up on your custom control class's Height and Width.

 

For the first part, having ButtonHeight and ButtonWidth is just Weird. Overriding Height/Width property and having a new implementation is much better option if we can get around third problem. This means every control will have Height/Width property as follows...

         public new double Height
        {
            get { return ((FrameworkElement)this).Height; }
            set
            {
                ((FrameworkElement)this).Height = value;
                UpdateLayout();
            }
        }

        public new double Width
        {
            get { return ((FrameworkElement)this).Width; }
            set
            {
                ((FrameworkElement)this).Width = value;
                UpdateLayout();
            }
        }

This calls a method call UpdateLayout() which is responsible for updating all elements that constitute a "look" of the control.

for something simple such as progressbar control, UpdateLayout might look like this...

         void UpdateLayout()
        {
            _progressBarRoot.Height = Height;
            _progressBarRoot.Width = Width;

            _progressBarFillRectangle.Height = Height;
            _progressBarFillRectangle.Width = Width;

            _progressBarTrackRectangle.Height = Height;
            _progressBarTrackRectangle.Width = Width;
        }

Now for the third problem, we can use Loaded event to update height and width using update layout.

 this.Loaded += new EventHandler(ProgressBar_Loaded);

 

In the Loaded event handler, you can call UpdateLayout which updates the Height and Width. By the time, Loaded Event handler runs, parser has set the Height/Width property on the base class and UpdateLayout would update the visuals based on those values.

 

         void ProgressBar_Loaded(object sender, EventArgs e)
        {
            UpdateLayout();
        }