1

I am using Framework version 4.0,

My problem when Zoom, Canvas should not re-size. or children only zoom IN / OUT?

please suggest me.

Thanks

  • Welcome to StackOverflow. I suggest that you read through the help centre pages, in particular the page that explains [how to ask a good question](http://stackoverflow.com/help/how-to-ask). As you can see, you have already received a number of [close votes](http://stackoverflow.com/help/closed-questions) because your question has been considered to be a question of low quality. Reading the help pages should help you to ask a better question and receive answers. – Sheridan Oct 25 '13 at 11:44

2 Answers2

2

I have done this before, the solution I found was when ever the zoom-in, make zoom out to the items I want keep the same size.

So, the zoom is a scale transform, then always when the scale transform in the container zoom item increase, you need to apply a decreasing transform to the items (the items you want keep the size). Here I have a sample code of an attached property that you can use later in xaml code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using Cepha.View.Converter;
using Cepha.View.Util;
using Microsoft.Practices.ServiceLocation;
using WPFExtensions.Controls;

namespace Cepha.View.AttachedProperty
{
    public static class KeepSizeOnZoomBehavior
    {
        #region KeppSizeOnZoom

    public static bool GetKeppSizeOnZoom(DependencyObject obj)
    {
        return (bool) obj.GetValue(KeppSizeOnZoomProperty);
    }

    public static void SetKeppSizeOnZoom(DependencyObject obj, bool value)
    {
        obj.SetValue(KeppSizeOnZoomProperty, value);
    }

    // Using a DependencyProperty as the backing store for KeppSizeOnZoom.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty KeppSizeOnZoomProperty =
        DependencyProperty.RegisterAttached("KeppSizeOnZoom", typeof (bool), typeof (KeepSizeOnZoomBehavior),
                                            new PropertyMetadata(false, OnKeepSizeOnZoomPropertyChanged));

    private static void OnKeepSizeOnZoomPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var uiElement = d as UIElement;
        if (uiElement == null)
            return;

        if ((bool)e.NewValue)
        {

            var zoomContentPresenter = ViewUtils.GetParent(d, p => p is ZoomContentPresenter) as ZoomContentPresenter;
            if (zoomContentPresenter == null)
                return;
            if (zoomContentPresenter.RenderTransform == null || !(zoomContentPresenter.RenderTransform is TransformGroup))
                return;

            var sourceScaleTransform =
                (zoomContentPresenter.RenderTransform as TransformGroup).Children.FirstOrDefault(
                    c => c is ScaleTransform) as ScaleTransform;

            if (sourceScaleTransform == null)
                return;



            if (uiElement.RenderTransform == null || !(uiElement.RenderTransform is TransformGroup))
            {
                uiElement.RenderTransform = new TransformGroup();
            }
            var scaleTransform =
                (uiElement.RenderTransform as TransformGroup).Children.FirstOrDefault(c => c is ScaleTransform) as
                ScaleTransform;


            var inverseConverter = ServiceLocator.Current.GetInstance<InverseConverter>();

            if (scaleTransform == null)
            {
                scaleTransform =
                    new ScaleTransform(
                        (double) inverseConverter.Convert(sourceScaleTransform.ScaleX, typeof (double), null, null),
                        (double) inverseConverter.Convert(sourceScaleTransform.ScaleY, typeof (double), null, null), 0,
                        0);
                (uiElement.RenderTransform as TransformGroup).Children.Add(scaleTransform);
            }

            BindingOperations.SetBinding(scaleTransform, ScaleTransform.ScaleXProperty,
                                         new Binding("ScaleX")
                                             {Source = sourceScaleTransform, Converter = inverseConverter});
            BindingOperations.SetBinding(scaleTransform, ScaleTransform.ScaleYProperty,
                                         new Binding("ScaleY")
                                             {Source = sourceScaleTransform, Converter = inverseConverter});
            if (d is FrameworkElement)
            {
                (d as FrameworkElement).Unloaded += OnElementUnloaded;
            }
        }
        else
        {
            ClearScaleYXBinding(uiElement);
        }
    }

    private static void OnElementUnloaded(object sender, RoutedEventArgs e)
    {
        var uiElement = sender as UIElement;
        if (uiElement == null)
            return;
        ClearScaleYXBinding(uiElement);
        ((FrameworkElement) sender).Unloaded -= OnElementUnloaded;
    }

    private static void ClearScaleYXBinding(UIElement uiElement)
    {
        if (!(uiElement.RenderTransform is TransformGroup))
            return;
        var scaleTransform =
            (uiElement.RenderTransform as TransformGroup).Children.FirstOrDefault(c => c is ScaleTransform) as
            ScaleTransform;
        if (scaleTransform == null)
            return;
        BindingOperations.ClearBinding(scaleTransform, ScaleTransform.ScaleXProperty);
        BindingOperations.ClearBinding(scaleTransform, ScaleTransform.ScaleYProperty);
    }

    #endregion
}
}

The inverse converter:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Data;

namespace Cepha.View.Converter
{
    public class InverseConverter:IValueConverter
    {
        #region Implementation of IValueConverter

    /// <summary>
    /// Converts a value. 
    /// </summary>
    /// <returns>
    /// A converted value. If the method returns null, the valid null value is used.
    /// </returns>
    /// <param name="value">The value produced by the binding source.</param><param name="targetType">The type of the binding target property.</param><param name="parameter">The converter parameter to use.</param><param name="culture">The culture to use in the converter.</param>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is double)
            return 1/(double) value;
        return 1/(float) value;
    }

    /// <summary>
    /// Converts a value. 
    /// </summary>
    /// <returns>
    /// A converted value. If the method returns null, the valid null value is used.
    /// </returns>
    /// <param name="value">The value that is produced by the binding target.</param><param name="targetType">The type to convert to.</param><param name="parameter">The converter parameter to use.</param><param name="culture">The culture to use in the converter.</param>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is double)
            return 1 / (double)value;
        return 1 / (float)value;
    }

    #endregion
}
}

You can use this in styles:

<Style x:Key="PointListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
        <Setter Property="Background" Value="Transparent"/>
        ...
        <Setter Property="AttachedProperty:KeepSizeOnZoomBehavior.KeppSizeOnZoom" Value="True"/>
...

Or you can use it directly on visual items:

<Buttom AttachedProperty:KeepSizeOnZoomBehavior.KeppSizeOnZoom="True" .../>

Try this, maybe helps you...


EDIT


The ViewUtil is a simple static class for helping in some manage things, here is the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;

namespace Cepha.View.Util
{
    public static class ViewUtils
    {
        public static bool AnyParent(DependencyObject item, Func<DependencyObject, bool> condition)
        {
            if (item == null)
                return false;

            var logicalParent = LogicalTreeHelper.GetParent(item);
            var visualParent = VisualTreeHelper.GetParent(item);

            return condition(item) || AnyParent(visualParent, condition);
        }

        public static DependencyObject GetParent(DependencyObject item, Func<DependencyObject, bool> condition)
        {
            if (item == null)
                return null;

            var logicalParent = LogicalTreeHelper.GetParent(item);
            var visualParent = VisualTreeHelper.GetParent(item);

            return condition(item) ? item : GetParent(visualParent, condition);
        }

        public static DependencyObject GetVisualChild(DependencyObject item, Func<DependencyObject, bool> condition)
        {
            if (item == null)
                return null;

            var q = new Queue<DependencyObject>();
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(item); i++)
            {
                var t = VisualTreeHelper.GetChild(item, i);
                if (condition(t))
                    return t;
                q.Enqueue(t);
            }

            while (q.Count > 0)
            {
                var subchild = q.Dequeue();
                for (int i = 0; i < VisualTreeHelper.GetChildrenCount(subchild); i++)
                {
                    var t = VisualTreeHelper.GetChild(subchild, i);
                    if (condition(t))
                        return t;
                    q.Enqueue(t);
                }
            }
            return null;
        }

        public static DependencyObject GetLogicalChild(DependencyObject item, Func<DependencyObject, bool> condition)
        {
            if (item == null)
                return null;

            var q = new Queue<DependencyObject>();
            foreach (var w in LogicalTreeHelper.GetChildren(item))
            {
                var t = w as DependencyObject;
                if (condition(t))
                    return t;
                q.Enqueue(t);
            }

            while (q.Count > 0)
            {
                var subchild = q.Dequeue();
                foreach (var w in LogicalTreeHelper.GetChildren(subchild))
                {
                    var t = w as DependencyObject;
                    if (condition(t))
                        return t;
                    q.Enqueue(t);
                }
            }
            return null;
        }
    }
}
Raúl Otaño
  • 4,640
  • 3
  • 31
  • 65
  • Thanks :) In AttachedProperty --> ViewUtils.GetParent(), giving error, ViewUtils is new class file or free define function? please let me know. – Sankaranarayanan Oct 28 '13 at 06:32
  • If this answer was useful, you should mark it as acepted answer, and if you consider, vote up. This helps other that has same problem to determine what answer may be useful for them. Also, I'm happy that finally works fine :) – Raúl Otaño Oct 29 '13 at 14:59
0

Assign a ScaleTransform instance to the RenderTransform property of your Canvas. Smaller values 'zoom' out, large values 'zoom' in.

If you were to use the LayoutTransform property of your canvas, the size would change.

A little light reading on transformations, from Microsoft: http://msdn.microsoft.com/en-us/library/ms750596.aspx

Gusdor
  • 14,001
  • 2
  • 52
  • 64