Domanda

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

È stato utile?

Soluzione

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;
        }
    }
}

Altri suggerimenti

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top