tags:

views:

607

answers:

1

I what to draw a circle that uniformly fits into its space, with a constant a stoke thickness. A ViewBox gets me the uniform fit, but not the constant stoke thickness.

<Viewbox Stretch="Uniform" MinHeight="10" MinWidth="10" >
    <Ellipse Height="10" Width="10" Fill="Red" StrokeThickness="1" Stroke="Yellow"/>
</Viewbox>
+2  A: 

If you don't specify a width or height of the ellipse, the default values will be "Auto". Combined with the default HorizontalAlignment/VerticalAligment values of "Stretch", this should cause the ellipse to "stretch" to the width and height of its container (with constant stroke thickness).

The *ContentAlignment properties of the parent container may affect this behavior, but again, the default, unset values should give you the behavior you want.

Edit: revising my suggestion because I did not realized the ellipse must remain a circle (don't worry, I've decided to pick up a copy of "Reading for Comprehension").

I suggest you bind the width and height properties of the ellipse to a MultiBinding of the parent container's ActualWidth and ActualHeight properties. Then implement a "multi-value converter" that will return the minimum value from the multi-binding.

So the converter might look like this:

class MinimumValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return values.Cast<double>().Min();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

And the ellipse properties could be bound like this:

<Window.Resources>
    <l:MinimumValueConverter x:Key="MinimumValueConverter" />
</Window.Resources>
<Ellipse Stroke="Black" StrokeThickness="1">
    <Ellipse.Width>
        <MultiBinding Converter="{StaticResource MinimumValueConverter}">
            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UIElement}}" Path="ActualWidth" />
            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UIElement}}" Path="ActualHeight" />
        </MultiBinding>
    </Ellipse.Width>
    <Ellipse.Height>
        <MultiBinding Converter="{StaticResource MinimumValueConverter}">
            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UIElement}}" Path="ActualWidth" />
            <Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UIElement}}" Path="ActualHeight" />
        </MultiBinding>
    </Ellipse.Height>
</Ellipse>
Daniel Pratt
But it is no longer a circle. :)
jyoung
It's a circle now. Thanks.
jyoung