我正在使用框架版本 4.0,
缩放时我的问题,画布不应该重新调整大小。还是儿童只放大/缩小?
请建议我。
谢谢
我以前做过这个,我找到的解决方案是在放大时,缩小到我想要保持相同大小的项目。
所以,缩放是一个缩放变换,那么当容器缩放项中的缩放变换增加时,您需要对项目(您希望保持大小的项目)应用减少变换。这里我有一个附加属性的示例代码,您可以稍后在 xaml 代码中使用它:
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
}
}
逆变器:
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
}
}
您可以在样式中使用它:
<Style x:Key="PointListBoxItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent"/>
...
<Setter Property="AttachedProperty:KeepSizeOnZoomBehavior.KeppSizeOnZoom" Value="True"/>
...
或者您可以直接在视觉项目上使用它:
<Buttom AttachedProperty:KeepSizeOnZoomBehavior.KeppSizeOnZoom="True" .../>
试试这个,也许对你有帮助...
编辑
ViewUtil 是一个简单的静态类,用于帮助管理一些事情,下面是代码:
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;
}
}
}
将ScaleTransform
实例分配给RenderTransform
您的Canvas
. 较小的值“缩小”,较大的值“放大”。
如果您要使用LayoutTransform
画布的属性,则大小会发生变化。
来自 Microsoft 的关于转换的一点浅读:http: //msdn.microsoft.com/en-us/library/ms750596.aspx