gpt4 book ai didi

WPF Canvas 和放置项目

转载 作者:行者123 更新时间:2023-12-04 05:20:49 26 4
gpt4 key购买 nike

我想要一个图像作为背景,可以均匀拉伸(stretch)。然后我希望我的 Canvas 的大小等于均匀拉伸(stretch)的图像。(我发现的一种解决方法是在网格内放置图像和 Canvas ,并将 Canvas 宽度/高度绑定(bind)到图像的实际高度/宽度)。

然后我想在 Canvas 内放置绝对定位的项目。但这就是问题所在。如果项目 X 为 50,图像宽度为 200px,则可以。但是如果图像宽度为 100px,项目 X 应该是 25。另外我想要一个小规模的转换。有没有办法通过绑定(bind)来实现这一点?我是否必须实现我的自定义面板用户控件,因为我看不到其他干净的解决方案。

最佳答案

您当然可以通过绑定(bind)实现所有这些,但我想创建一个派生面板会更容易和更清晰,该面板将子项安排在相对于面板的 ActualWidth 和 Actualheight 的位置。

派生的 Panel 类可以为子位置定义附加属性,类似于 Canvas.Left 和 Canvas.Top,但小数值范围从 0 到 1。

它还可以将背景图像作为依赖属性来维护。您将覆盖 OnRender直接绘制此图像的方法。

专家组还可以通过除以例如它的 ActualWidth 乘以图像的宽度。一个合适的ScaleTransform属性可以很容易地附加到每个 child 的 RenderTransform。

编辑:除了面板尺寸相对于背景图像的一致性外,以下内容可能会让您了解如何实现该面板:

public class ImagePanel : Panel
{
public static readonly DependencyProperty LeftProperty = DependencyProperty.RegisterAttached(
"Left", typeof(double), typeof(ImagePanel),
new FrameworkPropertyMetadata(PositionChanged));

public static readonly DependencyProperty TopProperty = DependencyProperty.RegisterAttached(
"Top", typeof(double), typeof(ImagePanel),
new FrameworkPropertyMetadata(PositionChanged));

public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
"Image", typeof(ImageSource), typeof(ImagePanel),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));

private ScaleTransform scaleTransform = new ScaleTransform();

public static double GetLeft(DependencyObject obj)
{
return (double)obj.GetValue(LeftProperty);
}

public static void SetLeft(DependencyObject obj, double value)
{
obj.SetValue(LeftProperty, value);
}

public static double GetTop(DependencyObject obj)
{
return (double)obj.GetValue(TopProperty);
}

public static void SetTop(DependencyObject obj, double value)
{
obj.SetValue(TopProperty, value);
}

public ImageSource Image
{
get { return (ImageSource)GetValue(ImageProperty); }
set { SetValue(ImageProperty, value); }
}

protected override void OnRender(DrawingContext dc)
{
if (Image != null)
{
dc.DrawImage(Image, new Rect(0d, 0d, ActualWidth, ActualHeight));
}

base.OnRender(dc);
}

protected override void OnRenderSizeChanged(SizeChangedInfo sizeInfo)
{
base.OnRenderSizeChanged(sizeInfo);

if (Image != null)
{
scaleTransform.ScaleX = sizeInfo.NewSize.Width / Image.Width;
scaleTransform.ScaleY = sizeInfo.NewSize.Height / Image.Height;
}
}

protected override Size MeasureOverride(Size availableSize)
{
foreach (UIElement element in InternalChildren)
{
element.Measure(availableSize);
}

return new Size();
}

protected override Size ArrangeOverride(Size finalSize)
{
foreach (UIElement element in InternalChildren)
{
element.RenderTransform = scaleTransform;
ArrangeElement(element, finalSize.Width, finalSize.Height);
}

return finalSize;
}

private static void PositionChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
var element = obj as UIElement;
var panel = VisualTreeHelper.GetParent(obj) as ImagePanel;

if (element != null && panel != null)
{
ArrangeElement(element, panel.ActualWidth, panel.ActualHeight);
}
}

private static void ArrangeElement(UIElement element, double width, double height)
{
var left = GetLeft(element);
var top = GetLeft(element);
var rect = new Rect(new Point(left * width, top * height), element.DesiredSize);

element.Arrange(rect);
}
}

关于WPF Canvas 和放置项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13722942/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com