Viewbox in Verbindung mit Canvas - Icongrösse anpassen

  • WPF

Es gibt 16 Antworten in diesem Thema. Der letzte Beitrag () ist von kafffee.

    Viewbox in Verbindung mit Canvas - Icongrösse anpassen

    Hallo zusammen,

    ich habe folgendes XAML:

    XML-Quellcode

    1. <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    2. <Viewbox Stretch="UniformToFill">
    3. <Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    4. <Path Fill="Black" Data="..."/>
    5. </Canvas>
    6. </Viewbox>
    7. </Border>


    Ich möchte, dass das Icon im Canvas in Zeile 4 (Path Data)auf die Grösse des Borders skaliert wird unter Berücksichtigung der Seitenverhältnisse. Was mache ich falsch?

    Und was ist der Unterschied zu Horizontal/Vertical Alignment (womit es leider auch nicht funktioniert)...

    Edit: ich probiers mal mit einem simplen:

    <Viewbox> <path Stretch = "Fill"... /> </Viewbox>

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kafffee“ ()

    versuch mal, das ganze mittels Binding zu lösen, indem du die Width-Eigenschaft des Canvas an die ActualWidth des Borders bindest und mit Height machst du es genauso.

    Entweder gibst du deinem Border einen Namen und bindest an den ElementName, oder du bindest via RelativeSource, FindAncestor

    Edit: Es kommt immer drauf an, wie das Control implementiert wurde, denn manche haben auch ein Horizontal/VerticalAlignment speziell für die Childelemente
    Moinsen. Kaffe: läuft. Batterie im Keyboard: Läuft. Zoom mit Seitenverhälnis: Läuft nicht.

    XML-Quellcode

    1. <Viewbox Stretch="Uniform">


    Das ist "Eigentlich" das mit dem Seitenverhältnis.

    Bei UniformToFill nimmt er die kleinste Kantenlänge und Zoomt diese ensprechend der Inhaltsfläche (Horiz./Vertikalkante des Elternelements).

    Der Path/Die Path/Das Path sollte die Width und Height angaben haben, denn in einem Canvas wird nicht "gezoomt".

    Das Canvas schaltet in seinem Kindergarten (Children) alle Skalierungen und Autopositionen ab.

    Es muss dann der Path Transformiert werden, und das hat mit einem Zoom nichts zu tun.
    Das bedeutet, wie der @PadreSperanza schon sagt, das Path-Element muss sich auf der Canvas-Zeichenfläche vergrößern.

    Es gäbe da die Möglichkeit ein ViewBox um das Path zu legen.
    Das Zoomt aber nicht, denn Dieses muss wirde eine "Bezugsgröße haben", und dann würd diese Viewbox ebenfalls in ein Border...
    Folglich muss irgendwann die angaben von Width und Height (in einem Canvas) geschehen.

    Also lieber gleich das Path-Element vergrößern und bewegen.

    Evtl. geht das einfacher mit "TranslateTransform"...

    Das ist zu beachten: Erst Bewegen, dann Verformen.

    So genug Translatiert. Ich mach mal den Transformer und ziehe mir was an...

    c.u. Joshi und Kafffeeeeeee :) 8-)

    kafffee schrieb:

    <Viewbox> <path Stretch = "Fill"... /> </Viewbox>


    Funktioniert nicht, obwohl es zwei Mal im Internet so drin steht...


    PadreSperanza schrieb:

    Entweder gibst du deinem Border einen Namen und bindest an den ElementName, oder du bindest via RelativeSource, FindAncestor


    Funktioniert auch nicht:

    XML-Quellcode

    1. <Path Data="..." Fill="Black" Width="{Binding ElementName=brdInterpretZuPlaylistZufügen, Path=ActualWidth}" Height="{Binding ElementName=brdInterpretZuPlaylistZufügen, Path=ActualHeight}"/>


    Und mit Layout/RenderTransform komm ich glaube ich auch nicht ans gewünschte Ziel... Da kann man das Icon ja nur nach Faktor skalieren und nicht nach Parentelementgrösse...

    Ich lass mich aber gern eines besseren belehren... Das muss doch irgendwie zu machen sein??

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kafffee“ ()

    Ja, genau es geht...

    Das Element auf das du dich Beziehst (die Zielgröße) , dort die größen ermitteln (oder daran Binden).

    Hast du ja gemacht...

    Ansonsten einmal manuell die Größen angeben und gucken ob das auch wirklich so geht.

    Ist denn das Border im Canvas oder ausserhalb?
    Hat das Border Festgelegte Gößen-Werte, oder werden die Berechnet?

    Hat die ViewBox auch Widht und Height?

    Und nicht vergessen "Uniform", das ist Seiteverhältnis-Skalierung mit Bezug auf kleinste Kante (Rahmenkante zu Inhalts-Objekt-Kante).

    uuups. Meeting Call muss weg... :D
    ich bin mir nicht sicher... aber müsstest du das Binding der ActualWidth/Height nicht eigtl auf das Canvas legen und nicht auf den Path?

    Weil wenn dein Path Werte hat wie "M 0,3 L 110,49" und du nun die Größe des Path veränderst, verändert sich die Größe deiner Linien nicht, sie werden nur in einer kleineren Form davon dargestellt, weil sie sich ja absolut zu ihrem Umfeld bewegen?
    Hi

    Joshi schrieb:

    Ansonsten einmal manuell die Größen angeben und gucken ob das auch wirklich so geht.

    Manuell festlegen geht. Aber ich will ja, wenn ich die Grösse des Fenster ändere oder gar das Programm mit einem Rechner mit anderer Auflösung läuft, sich das Icon anpasst...

    Joshi schrieb:

    Ist denn das Border im Canvas oder ausserhalb?
    Hat das Border Festgelegte Gößen-Werte, oder werden die Berechnet?

    Der Path ist im Canvas. Das Canvas ist in einem Border, und das Border in einem ListBoxItem...

    Joshi schrieb:

    Hat die ViewBox auch Widht und Height?

    Nein, aber probiert hab ich das auch... :(

    PadreSperanza schrieb:

    ich bin mir nicht sicher... aber müsstest du das Binding der ActualWidth/Height nicht eigtl auf das Canvas legen und nicht auf den Path?

    Auch das hab ich probiert...

    So wie ich das mittlerweile sehe ist kann man das Canvas auch getrost weglassen. Die Position des Icons soll ja eh 0, 0 sein...

    Ich versteh das echt nicht... Überall im Internet steht, dass das mit der Viewbox geht, tut es aber nicht... Ich hab das jetzt schon drei Mal gelesen...
    Weil für was soll eine Viewbox denn dann gut sein... Wenn nicht für solche Grafiken oder zur Darstellung von Text.. Bei den meisten anderen Controls kann man ja einfach Horizontal(Content)Alignment benutzen...

    Edit:
    @Nofear23m
    Hast du vielleicht noch ne Idee? Das gibts doch nicht das muss doch zu machen sein... bin mit meinem Latein am Ende...

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kafffee“ ()

    XML-Quellcode

    1. <Border>
    2. <Viewbox Stretch="Uniform" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
    3. <Canvas Width="24" Height="24" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
    4. <Path Fill="Black" Data="M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z" />
    5. </Canvas>
    6. </Viewbox>
    7. </Border>

    ????
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m

    Nope.... :(

    Ich weiss so müsste es doch gehen. Hab ich mehrfach auch im WWW gelesen...

    Kann das was damit zu tun haben, dass mein Border in einem Listbox Item drin ist? Weil ich weiss jetzt nicht mehr welche Kombination das war aber es kam vor, dass er mir das ganze auf die Grösse der gesamten Listbox skaliert hat...

    kafffee schrieb:

    Kann das was damit zu tun haben, dass mein Border in einem Listbox Item drin ist?

    Definitiv

    Wie immer.... Gib uns alle Details!!!
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hier die Listbox so wie sie ist:

    XML-Quellcode

    1. ​<ListBox Name="lstInterpreten" Grid.Column="0" Grid.Row="1" ItemsSource="{Binding AnzuzeigendeInterpreten}" SelectedItem="{Binding AusgewählterInterpret, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectionMode="Single" SelectedIndex="{Binding GewaehlterInterpret, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    2. <ListBox.ItemTemplate>
    3. <DataTemplate>
    4. <Grid>
    5. <Grid.ColumnDefinitions>
    6. <ColumnDefinition Width="5*"/>
    7. <ColumnDefinition Width="5*"/>
    8. <ColumnDefinition Width="90*"/>
    9. </Grid.ColumnDefinitions>
    10. <TextBlock Grid.Column="2" Text="{Binding Path=Interpret}">
    11. <ToolTipService.ToolTip>
    12. <StackPanel>
    13. <TextBlock Text="{Binding Path=Interpret}"/>
    14. </StackPanel>
    15. </ToolTipService.ToolTip>
    16. </TextBlock>
    17. <Border Name="brdInterpretZuPlaylistZufügen" Grid.Column="0" Style="{DynamicResource Navigationsbuttons}" ToolTip="Füge alle Musiktitel dieses Interpreten in zufälliger Reihenfolge der Playlist des gewählten Decks zu...">
    18. <Border.InputBindings>
    19. <MouseBinding MouseAction="LeftClick" Command="{Binding InterpretZuPlaylistZufügen}" CommandParameter="Zufügen"/>
    20. </Border.InputBindings>
    21. <Viewbox Stretch="UniformToFill">
    22. <Canvas Width="{Binding ElementName=brdInterpretZuPlaylistZufügen, Path=ActualWidth}" Height="{Binding ElementName=brdInterpretZuPlaylistZufügen, Path=ActualHeight}" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" HorizontalAlignment="Center" VerticalAlignment="Center">
    23. <Path Fill="{DynamicResource VordergrundfarbeBrush}" Data="M31 12h-11v-11c0-0.552-0.448-1-1-1h-6c-0.552 0-1 0.448-1 1v11h-11c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h11v11c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-11h11c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1z"/>
    24. </Canvas>
    25. </Viewbox>
    26. </Border>
    27. <Border Name="brdInterpretAbspielen" Grid.Column="1" Style="{DynamicResource Navigationsbuttons}" ToolTip="Spiele alle Musiktitel dieses Interpreten in zufälliger Reihenfolge auf dem gewählten Deck ab...">
    28. <Border.InputBindings>
    29. <MouseBinding MouseAction="LeftClick" Command="{Binding InterpretZuPlaylistZufügen}" CommandParameter="Zufügen"/>
    30. </Border.InputBindings>
    31. <!--<Canvas xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">-->
    32. <Path Height="8" Width="8" Stretch="UniformToFill" Fill="{DynamicResource VordergrundfarbeBrush}" Data="M6 4l20 12-20 12z"/>
    33. </Border>
    34. </Grid>
    35. </DataTemplate>
    36. </ListBox.ItemTemplate>
    37. </ListBox>


    Und in der Application.xaml:

    XML-Quellcode

    1. <Style TargetType="{x:Type ListBox}">
    2. <Setter Property="Background" Value="Transparent"/>
    3. <Setter Property="Foreground" Value="{DynamicResource VordergrundfarbeBrush}"/>
    4. <Setter Property="Margin" Value="10"/>
    5. <Setter Property="Opacity" Value="1"/>
    6. <Setter Property="BorderBrush" Value="{DynamicResource VordergrundfarbeBrush}"/>
    7. </Style>
    8. <Style TargetType="{x:Type ListBoxItem}">
    9. <Setter Property="Template">
    10. <Setter.Value>
    11. <ControlTemplate TargetType="ListBoxItem">
    12. <Border Name="_Border"
    13. Padding="1"
    14. SnapsToDevicePixels="true">
    15. <ContentPresenter />
    16. </Border>
    17. <ControlTemplate.Triggers>
    18. <Trigger Property="IsSelected" Value="true">
    19. <Setter TargetName="_Border" Property="Background" Value="Transparent"/>
    20. <Setter Property="Foreground" Value="White"/>
    21. <Setter TargetName="_Border" Property="BorderThickness" Value="1"/>
    22. <Setter TargetName="_Border" Property="BorderBrush" Value="{DynamicResource VordergrundfarbeBrush}"/>
    23. </Trigger>
    24. <Trigger Property="IsMouseOver" Value="True">
    25. <Setter TargetName="_Border" Property="BorderThickness" Value="1"/>
    26. <Setter TargetName="_Border" Property="BorderBrush" Value="{DynamicResource VordergrundfarbeBrush}"/>
    27. </Trigger>
    28. </ControlTemplate.Triggers>
    29. </ControlTemplate>
    30. </Setter.Value>
    31. </Setter>
    32. </Style>
    Hallo

    Also ich bau das jetzt nicht komplett nach wenn hier so viele Resources verwendet werden welche hier nicht mit reinkopiert werden, woher soll ich wissen wie der style "NavigationButtons" definiert ist.

    Fakt ist das du wenn du eine ViewBox definierst irgendwo die Grenzen setzen musst. Eine Viewbox streckt sich aus wie sie kann. Also z.b. am Border.

    XML-Quellcode

    1. ​ <Border Name="brdInterpretZuPlaylistZufügen" Width="16" Height="16" Grid.Column="0" ToolTip="Füge alle Musiktitel dieses Interpreten in zufälliger Reihenfolge der Playlist des gewählten Decks zu...">
    2. <Viewbox Stretch="Uniform">
    3. <Path Fill="Red" Data="M31 12h-11v-11c0-0.552-0.448-1-1-1h-6c-0.552 0-1 0.448-1 1v11h-11c-0.552 0-1 0.448-1 1v6c0 0.552 0.448 1 1 1h11v11c0 0.552 0.448 1 1 1h6c0.552 0 1-0.448 1-1v-11h11c0.552 0 1-0.448 1-1v-6c0-0.552-0.448-1-1-1z"/>
    4. </Viewbox>
    5. </Border>

    Das funzt bei mir tadellos. Bei dir nicht??

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m

    Da kommen wir der Sache schon näher. Default-Wert vom Border bei Horizontal/VerticalAlignment ist ja Stretch denke ich.
    Für mich sieht das im Endeffekt so aus, als ob sich das Listbox-Item der Grösse des Icons anpasst, aber halt nicht andersrum...

    Edit: Also hab ich in der Application.xaml im Style von ListboxItems der Horizontal/VerticalContentAlignment auf Stretch gesetzt. Keine Änderung... Wird das evtl. von meinem <Listbox.ItemTemplate> überschrieben??

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „kafffee“ ()

    Lieber Kafffee

    Lerne aus Fehlern, ich habs schonmal gesagt.

    Wenn es wo ein Problem gibt probiere es immer erst auf nem normalen Control auf dem nicht überschrieben wird, wo es keine Styles gibt und keine Templates überschrieben wurden.
    Dann kannst du Schritt für Schritt immer mehr dazu geben.
    Niemand von uns hat deine Konstellation, wir können in dem Fall nur raten.

    Du musst schon auch ein Stück weit probieren und daraus lernen.

    Und ja, ein ListboxItem kann sich der Größe anpassen, es muss nicht mal jedes gleich groß sein. Wie soll sich also ein Icon hier anpassen können? Wie gesagt, DU musst die Grenzen aufzeigen.

    Und ja, Strech ist der Standardwert: Siehe hier: docs.microsoft.com/en-us/dotne…ement_HorizontalAlignment

    Grüße
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Nofear23m schrieb:

    Du musst schon auch ein Stück weit probieren und daraus lernen.


    OK habs mal in einem Blankoprojekt versucht...erfolglos...

    Ich gehe davon aus, dass die Viewbox "feste Grenzen" braucht.

    Also hab ich jetzt einfach in meine Application.xaml eine feste Höhe für das Border als StaticResource festgelegt. Die effektive Schriftgrösse in den ListboxItems ändert sich ja auch nicht wenn das Fenster skaliert wird oder eine andere Auflösung herrscht... Also sollte das passen...

    Fertig ist die Laube :thumbsup:

    kafffee schrieb:

    Ich gehe davon aus, dass die Viewbox "feste Grenzen" braucht.

    Richtig! Das habe ich ja nun bereits zweimal geschrieben.
    Und war auch so in meinem Beispiel.
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##