none
Canvas mit Hintergrundbild und Childrens RRS feed

  • Frage

  • Hallo zusammen,

    ich habe eine kleine Herausforderung. :-) Ich habe ein Bild das ich in einem Canvas darstelle.
    Auf dem Bild platziere ich einen Textblock sowie mehrere Buttons über den Editor. In XAML
    habe ich dann ein Canvas.TOP und ein Canvas.Left Wert. Wenn ich jetzt die App in der Fenstergröße ändere
    dann bleiben die Buttons an ihrer ursprünglichen Position und wandern nicht mit der Imagegröße mit.
    Ich habe jetzt schon einiges gegoogelt bekomme es aber nicht hin. 
    Eine Viewbox als simpler Workarround funktioniert wie beschrieben auch nicht, meine Buttons sind dann im Hintergrund des Bildes. 
    Hat hier jemand ein Beispiel für mich? 

    Vielen Dank Gruß

    Michael

    Sonntag, 21. Januar 2018 19:21

Antworten

  • Hi Michael,
    Dein Canvas benötigt eine Vorgabe für eine Größe, die als Standard-Größe dient. Wenn jetzt der Canvas-Container in der Größe geändert wird, musst Du entscheiden, was passieren soll. Eine Möglichkeit ist die Skalierung. Dazu mal eine kleine Demo:

    XAML:

    <Page
        x:Class="UWP10App1VB.Page11"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:UWP10App1VB"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
      <Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Canvas.RenderTransform>
          <ScaleTransform ScaleX="{Binding ScaleFactor, Mode=OneWay}" ScaleY="{Binding ScaleFactor, Mode=OneWay}"/>
        </Canvas.RenderTransform>
        <Image>
          <Image.Source>
            <BitmapImage x:Name="imageSource"  UriSource="Assets/Bild.jpg"/>
          </Image.Source>
        </Image>
        <Button Content="Button" Canvas.Left="200" Canvas.Top="100" Background="Red"/>
      </Canvas>
    </Page>
    

    Und dazu der CodeBehind, wo auf eine Standardbreite von 500 proportional skaliert wird.

    Public NotInheritable Class Page11
      Inherits Page
      Implements INotifyPropertyChanged
    
      Private Sub Page11_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Me.DataContext = Me
      End Sub
    
      Public Property ScaleFactor As Double = 1
    
      Private Sub Page11_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged
        Scalefactor = e.NewSize.Width / 500
        OnPropertyChanged(NameOf(ScaleFactor))
      End Sub
    
      Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
      Friend Sub OnPropertyChanged(<CallerMemberName> Optional propName As String = "")
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
      End Sub
    
    End Class


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Montag, 22. Januar 2018 05:54

Alle Antworten

  • Hallo Michael,

    Du musst weg vom realen Werten zu prozentualen Werten. Ein Button könnte von Links 3,4236% und von ober 4.384% weg sein. Am einfachsten geht dies wenn Du dich erstmal für eine Fenstergröße entscheidest. Z.B. 1000x800. Dann positionierst Du deine Button und rechnest dann die Position in Prozent um. Bei jedem SizeChanged kann Du dann einfach die neue Position berechnen. 


    Gruß Thomas
    Sage nie, ich kann es nicht - sage nur, ich kann es noch nicht!
    Dev Apps von mir: Icon für UWP,  UI Strings
    Andere Dev Apps: UWP Community Toolkit Sample App

    Sonntag, 21. Januar 2018 20:55
  • Hi Michael,
    so richtig verstanden habe ich nicht, was Du machen willst. Das Canvas nutzt eine "feste" Positionierung der eingebetteten Steuerelemente. Wo sollen die Steuerelemente beim Ändern der Canvas-Größe hinwandern?

    Wenn die relative Positionierung der Steuerelemente unabhängig von der Größe des Canvas bestehen bleiben soll, dann nutze LayoutTransform. Mit dem ScaleX und ScaleY kannst Du proportional die Anzeige vergrößern oder verkleinern.


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Sonntag, 21. Januar 2018 21:02
  • Hallo Thomas hallo Peter,

    schau ich mir mal an mit den % Umrechnungen.... 

    @Peter 

    mein Canvas hatte keine feste Größe deswegen hat er es immer an die Größe des Fensters der Applikation angepasst. 
    wenn ich jetzt eine feste Größe vorgebe dann passt das ganze doch als bsp. nicht mehr auf ein 8 Zoll Device oder sehe ich das jetzt falsch?
    Oder muss ich dann wieder mit Trigger anfangen die dann die größe anpassen.


    Gruß Michael

    Sonntag, 21. Januar 2018 22:07
  • Das Problem bei Bilder ist grade das Seitenverhältnis. Solltest Du dich z.B. für 16:9 entscheiden was passiert bei 4:3. Du musst somit immer Bereiche definieren die nicht wichtig sind und deine Buttons entsprechend anpassen. Das ganze und zwar grade bei UWP ist eine riesige Herausforderung

    Gruß Thomas
    Sage nie, ich kann es nicht - sage nur, ich kann es noch nicht!
    Dev Apps von mir: Icon für UWP,  UI Strings
    Andere Dev Apps: UWP Community Toolkit Sample App

    Sonntag, 21. Januar 2018 22:57
  • Hi Michael,
    Dein Canvas benötigt eine Vorgabe für eine Größe, die als Standard-Größe dient. Wenn jetzt der Canvas-Container in der Größe geändert wird, musst Du entscheiden, was passieren soll. Eine Möglichkeit ist die Skalierung. Dazu mal eine kleine Demo:

    XAML:

    <Page
        x:Class="UWP10App1VB.Page11"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:UWP10App1VB"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
      <Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Canvas.RenderTransform>
          <ScaleTransform ScaleX="{Binding ScaleFactor, Mode=OneWay}" ScaleY="{Binding ScaleFactor, Mode=OneWay}"/>
        </Canvas.RenderTransform>
        <Image>
          <Image.Source>
            <BitmapImage x:Name="imageSource"  UriSource="Assets/Bild.jpg"/>
          </Image.Source>
        </Image>
        <Button Content="Button" Canvas.Left="200" Canvas.Top="100" Background="Red"/>
      </Canvas>
    </Page>
    

    Und dazu der CodeBehind, wo auf eine Standardbreite von 500 proportional skaliert wird.

    Public NotInheritable Class Page11
      Inherits Page
      Implements INotifyPropertyChanged
    
      Private Sub Page11_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Me.DataContext = Me
      End Sub
    
      Public Property ScaleFactor As Double = 1
    
      Private Sub Page11_SizeChanged(sender As Object, e As SizeChangedEventArgs) Handles Me.SizeChanged
        Scalefactor = e.NewSize.Width / 500
        OnPropertyChanged(NameOf(ScaleFactor))
      End Sub
    
      Public Event PropertyChanged As PropertyChangedEventHandler Implements INotifyPropertyChanged.PropertyChanged
      Friend Sub OnPropertyChanged(<CallerMemberName> Optional propName As String = "")
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propName))
      End Sub
    
    End Class


    --
    Viele Grüsse
    Peter Fleischer (ehem. MVP)
    Meine Homepage mit Tipps und Tricks

    Montag, 22. Januar 2018 05:54
  • Hallo Peter,

    kann leider erst heute antworten. Vielen Dank für dein Beispiel. Ich habe es hinbekommen.

    Gruß

    Michael

    Samstag, 10. Februar 2018 13:32