none
[WPF][C#] System.Windows.Controls.ScrollViewer - Zoom ausschalten

    Frage

  • Moin allerseits,

    ich verwende in einem "on the fly" WPF Proggi einen System.Windows.Controls.ScrollViewer mit einem Canvas darin.

    Wenn ich das Element in einer Windows Forms Anwendung verwendet habe, konnte ich den Zoom ausschalten um das Originalbild zu bekommen.

    Das klappt in WPF anscheinend nicht !

    scroll_viewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible;
    scroll_viewer.VerticalScrollBarVisibility = ScrollBarVisibility.Visible;
    scroll_viewer.RenderTransform = System.Windows.Media.Transform.Identity;
    scroll_viewer.LayoutTransform = System.Windows.Media.Transform.Identity;
    scroll_viewer.Content = m_canvas;

    Ich habe das Internet durchsucht, die Microsoft Doku, aber ich finde keine Lösung, mein Bild ( Canvas mit Background ) wird immer skaliert.

    Hat jemand eine Ahnung was zu tun ist ?

    Danke,

    Charlie Brown

    Montag, 12. Februar 2018 16:29

Antworten

  • Hi Charlie,
    vergleiche mal mit einem großen Bild:

      <ScrollViewer HorizontalScrollBarVisibility="Visible"
                       VerticalScrollBarVisibility="Visible">
        <Canvas Height="1000" Width="1000">
          <Image Source="Bild.jpg"/>
        </Canvas>
      </ScrollViewer>

    Und jetzt ohne Canvas-Große:

      <ScrollViewer HorizontalScrollBarVisibility="Visible"
                       VerticalScrollBarVisibility="Visible">
        <Canvas>
          <Image Source="Bild.jpg"/>
        </Canvas>
      </ScrollViewer>


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

    Dienstag, 13. Februar 2018 20:57
  • Hi Charlie,
    keine Ahnung, was Du anders gemacht hast. Hier mal meine Demo:

    XAML:

    <Window x:Class="WpfApp1CS.Window33"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1CS"
            mc:Ignorable="d"
            Title="Window33" Height="300" Width="300" Loaded="Window_Loaded">
      <Grid>
        <ScrollViewer Name="scroll_viewer"
            HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
        </ScrollViewer>
      </Grid>
    </Window>

    Und der CodeBehind:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    
    namespace WpfApp1CS
    {
      /// <summary>
      /// Interaction logic for Window33.xaml
      /// </summary>
      public partial class Window33 : Window
      {
        public Window33()
        {
          InitializeComponent();
        }
    
        ImageBrush m_canvas_brush;
        Canvas m_canvas;
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
          BitmapImage bmi = new BitmapImage(new Uri(@"bild.jpg", UriKind.Relative));
          m_canvas_brush = new ImageBrush(bmi);
          m_canvas_brush.AlignmentX = AlignmentX.Left;
          m_canvas_brush.AlignmentY = AlignmentY.Top;
          m_canvas_brush.Stretch = Stretch.None;
          m_canvas = new Canvas();
          m_canvas.HorizontalAlignment = HorizontalAlignment.Left;
          m_canvas.VerticalAlignment = VerticalAlignment.Top;
          m_canvas.Width = bmi.Width;
          m_canvas.Height = bmi.Height;
          m_canvas.Visibility = Visibility.Visible;
          m_canvas.Background = m_canvas_brush;
          scroll_viewer.Content = m_canvas;
        }
      }
    }


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

    Donnerstag, 15. Februar 2018 18:10

Alle Antworten

  • Hi Charlie,
    wenn das Canvas-Steuerelement keine eigene Größe größer als der Container hat, in dem sich der ScrollViewer befindet, dann ist er unwirksam. Du müsstest also etwas detaillierter beschreiben, was Du machst und was Du erreichen willst.

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

    Montag, 12. Februar 2018 18:44
  • Hallo Peter,

    erst mal vielen Dank für deine Hilfe.

    Ich will "mal eben" ein Hilfsprogramm schreiben, das Texturen verarbeitet. ( .png )

    Dazu habe ich eine WPF Vorlage genommen und einen ScrollViewer im XAML hinzugefügt.

    Content des Viewers ist ein Canvas ( damit ich darauf Shapes darstellen kann ).

    Der Background des Canvas ist die Textur ( *.png ), per Brush aufgebracht.

    Tja, und da kommen die Probleme: Die Shapes ( in persona ein Rechteck ) werden in der korrekten Größe angezeigt, das Canvas hat laut Debugger die korrekte Größe, wird aber anscheinend im ScrollViewer verkleinert, wodurch das Rechteck nicht wie geplant den passenden Ausschnitt der Textur anzeigt.

    Ich habe so etwas ähnliches schon mal in Windows Forms gemacht, da kann man den Zoom des ScrollViewers abschalten.

    Jetzt aber habe ich mich an WPF festgebissen und hoffe auf eine ähnliche Lösung.

    Hast du einen Tip für mich ?

    Charlie Brown

    Dienstag, 13. Februar 2018 18:07
  • Hi Charlie,
    vergleiche mal mit einem großen Bild:

      <ScrollViewer HorizontalScrollBarVisibility="Visible"
                       VerticalScrollBarVisibility="Visible">
        <Canvas Height="1000" Width="1000">
          <Image Source="Bild.jpg"/>
        </Canvas>
      </ScrollViewer>

    Und jetzt ohne Canvas-Große:

      <ScrollViewer HorizontalScrollBarVisibility="Visible"
                       VerticalScrollBarVisibility="Visible">
        <Canvas>
          <Image Source="Bild.jpg"/>
        </Canvas>
      </ScrollViewer>


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

    Dienstag, 13. Februar 2018 20:57
  • Hallo Peter,

    hat leider nicht geklappt - kein Problem, da es nur ein kurzes Testprogramm ist, steige ich wieder um auf Windows Forms und widme mich ein anderes Mal den Geheimnissen von WPF Programmen.

    VIELEN DANK für deine Hilfe,

    Charlie Brown

    Mittwoch, 14. Februar 2018 17:14
  • Hi Charlie,
    solange Du nicht etwas genauer beschreibst, was Du erreichen willst, ist es schwer zu helfen.

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

    Mittwoch, 14. Februar 2018 18:36
  • OK, da gebe ich dir Recht, aber ich wollte nicht mit Details langweilen - also noch mal von vorne:

    ( By the way: Ich habe den ScrollViewer nicht in Windows Forms, sondern als UI Element in einem UWP Proggi genutzt - freudsche Fehlleistung meinerseits )

    Ich möchte in einem WPF Programm eine Bitmap ( Typ *.png ) laden und darstellen.

    Diese Bitmap soll im ScrollViewer in der kompletten Größe angezeigt werden und würde ich gerne mit der Maus einen Ausschnitt wählen ( dafür war das Shape Rechteck gedacht ) um den Ausschnitt als separate Bitmap zu bearbeiten und zu speichern.

    Dazu habe ich ein Canvas im C# Code definiert ( der ScrollViewer ist in XAML definiert ) und die Bitmap wird in der Ladefunktion in den Brush geladen:

    m_canvas_brush = new ImageBrush(); m_canvas_brush.AlignmentX = AlignmentX.Left; m_canvas_brush.AlignmentY = AlignmentY.Top; m_canvas_brush.Stretch = Stretch.None; m_canvas = new Canvas(); m_canvas.HorizontalAlignment = HorizontalAlignment.Left; m_canvas.VerticalAlignment = VerticalAlignment.Top; m_canvas.Width = 0; m_canvas.Height = 0; m_canvas.Visibility = Visibility.Visible; m_canvas.Background = m_canvas_brush;

    scroll_viewer.Content = m_canvas;

    Die Ladefunktion:

    private void button_load_source_Click(object sender, RoutedEventArgs e)
            {
                // Source Textur laden ( gesamtes Bild )
                OpenFileDialog dlg = new OpenFileDialog();
                if (dlg.ShowDialog() == true)
                {
                    m_source_bitmap = new Bitmap(dlg.FileName);
                    m_canvas.Width = m_source_bitmap.Width;
                    m_canvas.Height = m_source_bitmap.Height;
                    m_canvas_brush.ImageSource = new BitmapImage(new Uri(@dlg.FileName, UriKind.Relative));
                }
            }

    Tja, und dann wird die Bitmap im Canvas / ScrollViewer angezeigt, aber leider in der falschen Größe, so das ich mit der Maus nicht den richtigen Ausschnitt erwische.

    Falls dir dazu noch was einfällt: Ich bin für jeden Tip dankbar, ansonsten switche ich wieder auf UWP um und nutze

    scroll_viewer.ZoomMode = ZoomMode.Disabled;

    Danke,

    Charlie Brown

    Donnerstag, 15. Februar 2018 16:02
  • Hi Charlie,
    wie ich Dir bereits geschrieben hatte, passt sich das Canvas an den äußeren Container an, wenn keine Größen angegeben wurden. So geht es aber z.B.:

          BitmapImage bmi = new BitmapImage(new Uri(@"bild.jpg", UriKind.Relative));
          m_canvas_brush = new ImageBrush(bmi);
          m_canvas_brush.AlignmentX = AlignmentX.Left;
          m_canvas_brush.AlignmentY = AlignmentY.Top;
          m_canvas_brush.Stretch = Stretch.None;
          m_canvas = new Canvas();
          m_canvas.HorizontalAlignment = HorizontalAlignment.Left;
          m_canvas.VerticalAlignment = VerticalAlignment.Top;
          m_canvas.Width = bmi.Width;
          m_canvas.Height = bmi.Height;
          m_canvas.Visibility = Visibility.Visible;
          m_canvas.Background = m_canvas_brush;
          scroll_viewer.Content = m_canvas;


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

    Donnerstag, 15. Februar 2018 17:18
  • Hallo Peter,

    ich habe den Code in die Ladefunktion kopiert und in der Init Funktion gelöscht.

    Das Ergebnis beim Laden ist das selbe ( die Bitmap wird nur mit 50% ihrer Größe angezeigt ).

    Irgend etwas mache ich falsch oder stelle es falsch ein !

    Danke,

    Charlie Brown

    Donnerstag, 15. Februar 2018 18:00
  • Hi Charlie,
    keine Ahnung, was Du anders gemacht hast. Hier mal meine Demo:

    XAML:

    <Window x:Class="WpfApp1CS.Window33"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
            xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
            xmlns:local="clr-namespace:WpfApp1CS"
            mc:Ignorable="d"
            Title="Window33" Height="300" Width="300" Loaded="Window_Loaded">
      <Grid>
        <ScrollViewer Name="scroll_viewer"
            HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
        </ScrollViewer>
      </Grid>
    </Window>

    Und der CodeBehind:

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    
    namespace WpfApp1CS
    {
      /// <summary>
      /// Interaction logic for Window33.xaml
      /// </summary>
      public partial class Window33 : Window
      {
        public Window33()
        {
          InitializeComponent();
        }
    
        ImageBrush m_canvas_brush;
        Canvas m_canvas;
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
          BitmapImage bmi = new BitmapImage(new Uri(@"bild.jpg", UriKind.Relative));
          m_canvas_brush = new ImageBrush(bmi);
          m_canvas_brush.AlignmentX = AlignmentX.Left;
          m_canvas_brush.AlignmentY = AlignmentY.Top;
          m_canvas_brush.Stretch = Stretch.None;
          m_canvas = new Canvas();
          m_canvas.HorizontalAlignment = HorizontalAlignment.Left;
          m_canvas.VerticalAlignment = VerticalAlignment.Top;
          m_canvas.Width = bmi.Width;
          m_canvas.Height = bmi.Height;
          m_canvas.Visibility = Visibility.Visible;
          m_canvas.Background = m_canvas_brush;
          scroll_viewer.Content = m_canvas;
        }
      }
    }


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

    Donnerstag, 15. Februar 2018 18:10
  • Ich hab jetzt mal deinen Code in einem neuen Projekt benutzt - immer noch das gleiche Problem.

    Die auf dem Bildschirm angezeigte Bitmap ist zu klein.

    Zum Vergleich halte ich einfach ein Paint Fenster ( ohne scaling ) daneben oder den Microsoft Foto Viewer,

    das Ergebnis ist das Gleiche.

    Muss irgendwo an meinem Rechner liegen, oder in meinen Einstellungen.

    Danke für deine Mühe, ich werd mal weiter basteln,

    Charlie

    Samstag, 17. Februar 2018 06:37
  • Hi Charlie,
    läuft denn mein Projekt (ohne Änderungen) bei Dir wie gewünscht? Dazu einfach mal alles in ein leeres Projekt kopieren. Wenn es nicht wie gewünscht läuft, dann beschreibve mal etwas genauer, was Dir nicht passt. Vielleicht reden wir auch aneinander vorbei.


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



    Samstag, 17. Februar 2018 09:16
  • Jepp, dein Projekt läuft, aber die Bitmap wird zu klein angezeigt.

    Ich habe also dein Projekt in ein leeres kopiert und es passiert immer das selbe:

    Die angezeigte Bitmap hat die Hälfte der Originalgröße ( ist auf 50% verkleinert ).

    Ich brauche die Originalgröße.

    Gruß,

    Charlie Brown

    Samstag, 17. Februar 2018 14:16
  • Hi Charlie,
    und wie sehen die Skalierungseinstellungen aus:


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


    Samstag, 17. Februar 2018 16:21
  • vor 13 Stunden 49 Minuten
  • Hi Charlie,
    und genau bei diesen Einstellungen wird bei meinem geposteten Cod das Bild in der vorgegeben Größe (Pixel) 1:1 auf dem Bildschirm dargestellt. Ein Bild mit 1000 Pixel Breite belegt die Hälfte der Bildschirmbreite. Erst, wenn ich auch LayoutTrasform mit ScaleTransform nutze, ändert sich die Größe der Darstellung.

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

    vor 11 Stunden 20 Minuten
  • Hallo Peter,

    dann muss ich vermutlich mal meinen Rechner auf Herz und Nieren überprüfen !

    Erst mal Vielen Dank für deine Mühe, das hier ist ein ziemlich langer task für ein "simples" Problem geworden.

    Ich werde weiter daran arbeiten, sollte ich eine Lösung finden, dann werde ich sie hier posten.

    Danke,

    Charlie 

    vor 10 Stunden 10 Minuten