Laden...

CustomControl - Zeichnen auf Canvas mit Skala von 0.0 bis 1.0 anstatt width und height

Erstellt von Viper2000 vor 3 Jahren Letzter Beitrag vor 3 Jahren 579 Views
V
Viper2000 Themenstarter:in
63 Beiträge seit 2008
vor 3 Jahren
CustomControl - Zeichnen auf Canvas mit Skala von 0.0 bis 1.0 anstatt width und height

Hallo,

ich bin gerade ein WPF Custom Control am Entwickeln. Es wird ein analoges Thermometer. Also ein Control, dem man eine Temperatur geben kann und der Zeiger wandert dann an die Position.

Jetzt ist es so, dass ich in meiner Generic.xaml einen Style definiert habe der die Elemente des Controls beinhaltet (Ellipse mit Gradient als Hintergrund, Zeiger als Path usw.).

Da das Control später beliebig in andere Proejkte eingebunden werden soll, stelle ich mir die Frage wie ich die Elemente im Control skalenunabhängig zeichnen kann. Ich würde also gerne das Koordinatensystem des Controls auf 0 bis 1 skalieren und darin alles unabhängig von der späteren tatsächlichen Größe zeichnen. Wenn jemand später dieses Control einbindet, soll in der XAML über Width und Height der User die Größe des Controls Festlegen können.

Sowas ähnliches hatte ich in Android schonmal gemacht. Da gibt es folgende Lösung:


float scale = (float) getWidth();		
canvas.save(Canvas.MATRIX_SAVE_FLAG);
canvas.scale(scale, scale);

Hat jemand einen Denkanstoß wie ich das bewerkstelligen kann?

5.658 Beiträge seit 2006
vor 3 Jahren

Es gibt zwei verschiedene Herangehensweisen:

Wenn jemand später dieses Control einbindet, soll in der XAML über Width und Height der User die Größe des Controls Festlegen können.

Dann würdest du aber verhindern, daß das Control auch über die automatischen Layout-Funktionen skaliert werden kann.

Weeks of programming can save you hours of planning

V
Viper2000 Themenstarter:in
63 Beiträge seit 2008
vor 3 Jahren

Danke schonmal für die Antwort! Ich habe nun ein Grid anstatt einen Canvas genommen und die Hintergrund Ellipse in meinem Style passt sich auch der Größe des umgebenden Elements an wenn ich das CustomControl in einem Testprojekt in z.B. einem Stackpanel einbinde.
Mir ist aber noch nicht ganz klar wie ich weiter Elemente im Style meines Custom Controls zeichnen kann die später auch auf die größe des umgebenden Containers Skaliert werden. Wenn man sich das Thermometer vorstellt soll auch der Zeiger und die Skala usw. proportional zur größe des umgebenden Containers skaliert werden. Zum besseren Verständnis hier mien XAML. Die zweite Ellipse mit dem Namen "PART_Middle" soll auch nicht mit einer festen Height und Width gezeichnet werden sondern erstmal unabhängig. Und da stehe ich auf dem Schlauch:


<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:local="clr-namespace:VintageHandMeterView">
    <Style TargetType="local:VintageHandMeterView">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:VintageHandMeterView">
                    <Grid x:Name="outerGrid">
                        <!--<Ellipse x:Name="PART_Background" Stroke="#4f333633" StrokeThickness="1" Width="{Binding Path=Width, ElementName=outerGrid}" Height="{Binding Path=Height, ElementName=outerGrid}">-->
                        <Ellipse x:Name="PART_Background" Stroke="#4f333633" StrokeThickness="1">
                            <Ellipse.Effect>
                                <DropShadowEffect ShadowDepth="2.0"/>
                            </Ellipse.Effect>
                            <Ellipse.Fill>
                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                                    <LinearGradientBrush.GradientStops>
                                        <GradientStop Color="#F0F5F0" Offset="0.0"/>
                                        <GradientStop Color="#303130" Offset="1.0"/>
                                    </LinearGradientBrush.GradientStops>
                                </LinearGradientBrush>
                            </Ellipse.Fill>
                        </Ellipse>
                        <Ellipse x:Name="PART_Middle" Stroke="Black" StrokeThickness="1" Fill="Black" Width="10" Height="10">

                        </Ellipse>
                        <!--<Grid.RenderTransform>
                            <ScaleTransform ScaleX="0.5" ScaleY="0.5" CenterX="{Binding Path=Width, ElementName=outerGrid, Mode=OneWay}" CenterY="125"/>
                        </Grid.RenderTransform>-->
                    
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</ResourceDictionary>

5.658 Beiträge seit 2006
vor 3 Jahren

Ich würde die zweite Variante bevorzugen. Erstelle eine Canvas mit fester Höhe und Breite, zeichne alles in absoluten Koordinaten, und laß dann alles in einer ViewBox auf die tatsächliche Größe des Controls skalieren.

Weeks of programming can save you hours of planning

V
Viper2000 Themenstarter:in
63 Beiträge seit 2008
vor 3 Jahren

Vielen Dank für die Hilfe!
Ich habe alles wie vorgeschlagen auf einem Canvas absolut gezeichnet und eine ViewBox drumherum gesetzt. Damit ist das Problem gelöst. 😃