tags:

views:

73

answers:

3

I create the following WPF control a dot and a description label: * North Star

<UserControl x:Class="StopPoint.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
    <Canvas>
        <Path Fill="SkyBlue" Stroke="Black" StrokeThickness="2">
            <Path.Data>
                <EllipseGeometry Center="10, 10" RadiusX="4" RadiusY="4"/>
            </Path.Data>
        </Path>
        <TextBlock Text="North Star" Canvas.Left="20" Canvas.Top="20"/>
    </Canvas>
</UserControl>

I will have a lot of stars in the panel. Can I autosize the control that is takes the minimum size possible?

Something à la : <Window SizeToContent="WidthAndHeight">...</Window>?

+1  A: 

How about wrapping it inside a simple stackpanel instead?

<UserControl x:Class="StopPoint.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

    <StackPanel Orientation="Horizontal">
        <Ellipse Margin="4" Stroke="Black" Fill="Yellow" Height="10" Width="10"/>
        <TextBlock Text="North Star">
            <TextBlock.RenderTransform>
                <RotateTransform Angle="45"/>
            </TextBlock.RenderTransform>
         </TextBlock>
    </StackPanel>
</UserControl>
Holstebroe
First of all, the problem is that the label's position shoud be customized. (radius and angle of text location), after that the user control d:DesignHeight="300" d:DesignWidth="300" is also bad...
serhio
The DesignHeight is just for convenience in the designer. Once you start using it in another control it doesn't matter. I have added a RotateTransform to the TextBlock. You can add any other transform or text effect to suit your needs as well. Canvas should be your last option.
Holstebroe
If you want to use a canvas you can wrap it in a Viewbox to control it's sizing, but that probably not get you the auto-sizing you want.
Holstebroe
this is cool... but the when rotated, the inscription goes over the ellipse... :")
serhio
Use the CenterX and CenterY properties of the RotateTransform to place the pivot point in the center of your star. You can also combine the RotationTransform with other transforms.
Holstebroe
+1  A: 

The d:DesignHeight/Width attributes are only respected in the designer, that is either the Blend or Visual Studio (Cider) designers. You can safely delete them and then you'll see in the designer your control without any constraints.

The auto-size behavior you describe is the default for many container controls. Try not to use a Canvas, like Holstebroe suggested. Also try to look into transforms instead - you can apply rotate and translate transforms to achieve the effects you describe.

Alex Paven
A: 

You got to create the autosize behavior in your usercontrol.

The WPF way is for the parents to ask the child elements how much space they need (measure phase) and then tell them how much space they actually got (arrange phase) based on the space available.

Here you want the parent's size to be dictated by the space required for the children. So bind the size of the top level parent (Canvas/UserControl) to the space required for the content - use an IMultiValueConverter to get multiple inputs for the summation. Refer to the link I posted about creating a usercontrol to get a centered text within a shape, which is an example of the above.
Once you have this, you can also do a 'fit to screen' using a Viewbox.

        <!-- 36 <= 20  (canvas.top) + 16 (textblock.actualheight) -->
        <!--75 <= 20 (canvas.left) + 55 (textblock.actualwidth)-->
        <Canvas Background="SkyBlue" Height="36" Width="75">
        <TextBlock Canvas.Left="25" Text="{Binding ElementName=label, Path=ActualHeight}"/>
        <Path x:Name="dot" Fill="SkyBlue" Stroke="Black" StrokeThickness="2">
                <Path.Data>
                    <EllipseGeometry Center="10, 10" RadiusX="4" RadiusY="4"/>
                </Path.Data>
            </Path>

        <TextBlock x:Name="label" Text="North Star" Canvas.Left="20" Canvas.Top="20"/>
Gishu