Vadim's Weblog

Never stop learning.

WPF Margin demystified.

Posted by Vadim on October 13, 2008

In my previous post I asked a question about this line of code:

<Button Margin="10 5" />

Question:

In XAML we can assign margin to a control three different ways:

<Button Margin="5" />
<Button Margin="10 5" />
<Button Margin="10 5 10 10" />
  • The first line assigns left, top, right, and bottom margins with value 5.
  • The second line assigns left and right margins with value 10 but top and bottom with value 5.
  • The last line assigns left, right, and bottom with value 10 and top would have value 5.

If we try to do the same in the code behind, it would look like this:

button.Margin = new Thickness(5);
button.Margin = new Thickness(10, 5, 10, 10);

You can see in the code above that we have code for line 1 & 3 only.  I couldn’t find the way to create code behind for second line because there’s no Thickness constructor with two parameters.

Thanks to Rune Jacobsen & Sam who provided some clues in comments to my previous article.

Answer:

After I read Sam’s comment:

The converter at work here is a ThicknessConverter which parses the input string and attempts to map the values given in the string to one of the Thickness object constructor overloads.

, I used .NET Reflector to analyze ThicknesseConverter class.

ThicknesseConveter has a public method ConvertFrom that calls internal method FromString.

public override object ConvertFrom(
    ITypeDescriptorContext typeDescriptorContext,
    CultureInfo cultureInfo,
    object source)
{
     . . .
    if (source is string)
    {
        return FromString((string) source, cultureInfo);
    }
     . . .
}

FromString method is responsible for parsing string values like “10, 5, 10, 10″ and converting them into Thickness.

It means that this code

<Button Margin="10 5" />

will be converted by FromString method into:

new Thickness(numArray[0], numArray[1], numArray[0], numArray[1]);

Bellow is a switch statement in FromString method that explains the magic.

internal static Thickness FromString(string s, CultureInfo cultureInfo)
{
     . . .
    switch (index)
    {
        case 1:
            return new Thickness(numArray[0]);
        case 2:
            return new Thickness(numArray[0], numArray[1], numArray[0], numArray[1]);
        case 4:
            return new Thickness(numArray[0], numArray[1], numArray[2], numArray[3]);
    }
     . . .
}

If you want to assign a margin with two doubles from the code behind, you can do it like this:

button.Margin =
    (Thickness)new ThicknessConverter()
        .ConvertFrom(null, CultureInfo.CurrentCulture, "5, 10");

Mystery is solved.

kick it on DotNetKicks.com

About these ads

2 Responses to “WPF Margin demystified.”

  1. Thanks for breaking down the Margin object. It seems that Margin is readonly property at least for User Control. Does this mean that one can not alter Margin during runtime ? Your presented code, does it actually compile ?

    Cannot modify the return value of ‘System.Windows.FrameworkElement.Margin’ because it is not a variable

  2. Reiseideen…

    WPF Margin demystified. « Vadim's Weblog…

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
Follow

Get every new post delivered to your Inbox.

%d bloggers like this: