The Artima Developer Community
Sponsored Link

.NET Buzz Forum
Unterschied zwischen LayoutTransform und RenderTransform in Zusammenhang mit einem ScrollViewer

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
-

Posts: 1524
Nickname: nitronic
Registered: Jul, 2006

Norbert Eder works as a software architect.
Unterschied zwischen LayoutTransform und RenderTransform in Zusammenhang mit einem ScrollViewer Posted: Feb 1, 2008 3:32 AM
Reply to this message Reply

This post originated from an RSS feed registered with .NET Buzz by -.
Original Post: Unterschied zwischen LayoutTransform und RenderTransform in Zusammenhang mit einem ScrollViewer
Feed Title: Norbert Eder - Living .NET
Feed URL: http://feeds.feedburner.com/NorbertEder-Livingnet
Feed Description: Copyright (c)2005, 2006 by Norbert Eder
Latest .NET Buzz Posts
Latest .NET Buzz Posts by -
Latest Posts From Norbert Eder - Living .NET

Advertisement
Kürzlich stand ich vor folgendem Problem: Gegeben ist ein ScrollViewer, darin enthalten ein Canvas. Auf letzterem Element werden andere Elemente platziert, die auch entsprechend verschoben werden können, wodurch eine Scroll-Funktionalität gegeben sein sollte. Nun mussten diese Elemente zoombar sein.

Bevor wir uns dem Sourcecode zuwenden, hier kurz das eigentliche Problem: Die Zoomfunktionalität wurde mittels ScaleTransform und RenderTransform (für den Typ UIElement verfügbar) umgesetzt. Im ersten Moment war jedoch verwunderlich, dass der ScrollViewer nicht ansprang und somit trotz vergrößerter Darstellung kein scrollen möglich war.

Nun ist es so, dass Objekte vom Typ FrameworkElement eine Methode LayoutTransform aufweisen, welche nicht nur auf das tatsächliche Element, sondern auf das gesamte Layout Auswirkung hat. Dies hat nun zur Folge, dass bei Verwendung von LayoutTransform der ScrollViewer anspringt und das gewünschte Ergebnis bringt, hingegen die Methode RenderTransform zwar die Elemente transformiert, jedoch das Layout davon unberührt läßt.

Hier nun das XAML eines Beispiels mit dem darauffolgenden Screenshot, damit man sich darunter auch etwas vorstellen kann:
<Window x:Class="WpfZoomDemo.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="525" Width="605">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="26"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ToolBar 
            Grid.Row="0" 
            Height="26" 
            x:Name="MainToolbar" 
            VerticalAlignment="Top">
            <ComboBox 
                x:Name="ZoomComboBox">
            </ComboBox>
            <ComboBox 
                x:Name="TransformType">
                <ComboBoxItem 
                    Content="RenderTransform" 
                    IsSelected="True"/>  
                <ComboBoxItem 
                    Content="LayoutTransform"/>
            </ComboBox>
        </ToolBar>
        <ScrollViewer 
            x:Name="ScrollViewer" 
            Grid.Row="1" 
            HorizontalScrollBarVisibility="Auto" 
            VerticalScrollBarVisibility="Auto">
            <Canvas x:Name="ButtonCanvas" 
                    Width="{Binding ElementName=ScrollViewer, 
                            Path=ActualWidth}"
                    Height="{Binding ElementName=ScrollViewer, 
                            Path=ActualHeight}">
                <Button 
                    Content="Button1" 
                    Margin="14 50 23 17" 
                    Height="19.998" 
                    Canvas.Left="49.995" 
                    Canvas.Top="181.8" 
                    Width="45.45" />
                <Button 
                    Content="Button2" 
                    Margin="14 50 23 17" 
                    Height="19.998" 
                    Canvas.Left="215.433" 
                    Canvas.Top="50.904" 
                    Width="45.45" />
                <Button 
                    Content="Button3" 
                    Margin="14 50 23 17" 
                    Height="19.998" 
                    Canvas.Left="232.704" 
                    Canvas.Top="264.519" 
                    Width="45.45" />
                <Button 
                    Content="Button4" 
                    Margin="14 50 23 17" 
                    Height="19.998" 
                    Canvas.Left="132.714" 
                    Canvas.Top="374.508" 
                    Width="45.45" />
                <Button 
                    Content="Button5" 
                    Margin="14 50 23 17" 
                    Height="19.998" 
                    Canvas.Left="425.412" 
                    Canvas.Top="196.344" 
                    Width="45.45" />
                <Button 
                    Content="Button6" 
                    Margin="14 50 23 17" 
                    Height="19.998" 
                    Canvas.Left="523.55" 
                    Canvas.Top="391.002" 
                    Width="45.45" />
            </Canvas>
        </ScrollViewer>
    </Grid>
</Window>

Und so sieht es aus:



Die nachfolgende Methode ist zuständig, um die tatsächliche Auswahl des Zoomfaktors auf den Canvas anzuwenden, d.h. der gesamte Canvas inkl. der Inhalte wird vergrößert. Zu beachten ist, dass durch diese Transformation die Veränderung der Größe nur temporär ist.
private void Zoom(double zoomfactor)
{
    ScaleTransform st = new ScaleTransform(zoomfactor, zoomfactor);
    if (TransformType.Text == "RenderTransform")
        ButtonCanvas.RenderTransform = st;
    else
        ButtonCanvas.LayoutTransform = st;
}

Hier ist ebenfalls zu sehen, dass auch die zweite ComboBox ausgewertet wird, damit auch der Unterschied ersichtlich ist.

Das Ergebnis mittels RenderTransform:


Das Ergebnis mittels LayoutTransform:


Damit das auch jeder ausprobieren kann, hier noch der gesamte Codebehind-Code:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;

namespace WpfZoomDemo
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            List<int> listToBind = new List<int>();
            listToBind.Add(25);
            listToBind.Add(50);
            listToBind.Add(75);
            listToBind.Add(100);
            listToBind.Add(125);
            listToBind.Add(150);
            listToBind.Add(200);
            listToBind.Add(300);

            BindToComboBox(
                listToBind, 
                this.ZoomComboBox);

            this.ZoomComboBox.SelectionChanged += 
                new SelectionChangedEventHandler
                    (ZoomComboBox_SelectionChanged);
        }

        void ZoomComboBox_SelectionChanged(
            object sender, 
            SelectionChangedEventArgs e)
        {
            IList selItems = e.AddedItems;
            if (selItems.Count > 0)
            {
                string selItem = selItems[0].ToString();
                int iZoomVal = 100;
                Int32.TryParse(selItem.Replace("%",""), 
                    out iZoomVal);
                Zoom((double)iZoomVal/100);
            }
        }

        private void BindToComboBox(
            List<int> listToBind, 
            ComboBox cBox)
        {
            if (!listToBind.Contains(100))
                listToBind.Add(100);

            listToBind.Sort();
            
            List<string> tempList = new List<string>();
            listToBind.ForEach(delegate(int itemValue) {
                if (!itemValue.ToString().Trim().EndsWith("%"))
                    tempList.Add(itemValue.ToString().Trim() + "%");
                else
                    tempList.Add(itemValue.ToString());
            });
            Binding b = new Binding();
            b.Source = tempList;
            cBox.SetBinding(ComboBox.ItemsSourceProperty, b);

            cBox.SelectedValue = "100%";
        }

        private void Zoom(double zoomfactor)
        {
            ScaleTransform st = 
                new ScaleTransform(zoomfactor, zoomfactor);
            if (TransformType.Text == "RenderTransform")
                ButtonCanvas.RenderTransform = st;
            else
                ButtonCanvas.LayoutTransform = st;
        }
    }
}

Wer also derartige Transformierungen durchführen möchte, der sollte sich durchaus überlegen, was davon alles betroffen sein soll. Auf dieser Basis sollte dann zwischen RenderTransform und LayoutTransform gewählt werden.

Read: Unterschied zwischen LayoutTransform und RenderTransform in Zusammenhang mit einem ScrollViewer

Topic: Mit List.ForEach durch Listen iterieren Previous Topic   Next Topic Topic: Ruby, Rails, RSpec, Rails Plugin, JavaScript, OS X

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use