3

Silverlight Canvas 类(带有 Reflector)有非常简单的实现:3 个附加的依赖属性(Left、Top、ZIndex)和 2 个 MeasureOverride 和 ArrangeOverride 方法的 ovverides,它们没有什么特别的。

但是,如果我使用我的实现,例如:

class MyCanvas : Panel { /* Top and Left dependency properties implementation */ }

然后像标准 Canvas 一样在 XAML 中使用 MyCanvas。这没有按预期工作(我看到空屏幕)。

Canvas 是如何实现的?

-- 附加代码:MyCanvas.cs

public class MyCanvas : Panel
{
    public static double GetTop(DependencyObject obj)
    {
        return (double)obj.GetValue(TopProperty);
    }

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

    // Using a DependencyProperty as the backing store for Top.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty TopProperty =
        DependencyProperty.RegisterAttached("Top", typeof(double), typeof(MyCanvas), new PropertyMetadata(0.0));


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

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

    // Using a DependencyProperty as the backing store for Left.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty LeftProperty =
        DependencyProperty.RegisterAttached("Left", typeof(double), typeof(MyCanvas), new PropertyMetadata(0.0));
}

在 XAML 中使用,例如:

<local:MyCanvas>
    <Rectangle 
        local:MyCanvas.Left="10"
        local:MyCanvas.Top="10"
        Width="100"
        Height="100"
        Fill="Black" />
</local:MyCanvas>

如果将 MyCanvas 更改为标准 Canvas,我可以在位置 10,10 处查看黑色填充矩形。

<Canvas>
    <Rectangle 
        Canvas.Left="10"
        Canvas.Top="10"
        Width="100"
        Height="100"
        Fill="Black" />
</Canvas>
4

3 回答 3

2

这似乎是 Reflector 的 Silverlight 反汇编引擎中的一个错误。您可以通过以下步骤构建自己的 Silverlight Canvas 控件:

  • 在 Reflector 中反汇编 WPF 画布控件并将代码复制到 Visual Studio。
  • 删除 DependencyProperties Bottom 和 Right,以及它们的 Get 和 Set 方法。
  • 从 ArrangeOverride 中删除 Bottom 和 Right 子句。
  • 将 FrameworkPropertyMetadata 替换为 PropertyMetadata。
  • 从 DependencyProperty 初始化中删除属性验证参数。

请注意,以这种方式创建的 Canvas 没有 ZIndex 属性。

于 2010-06-26T16:17:34.587 回答
0

正如您所说,Canvas 只不过是一个具有 Left 和 Top 附加属性的面板。根据MSDN

定义一个区域,您可以使用相对于该区域的坐标在该区域内显式定位子对象。

就是这样 - Canvas 可以在另一个 FrameworkElement 派生的容器内有一个明确的位置。如果您没有看到您的手卷画布,您可能会遇到渲染错误。您是否尝试过更改背景颜色以确保可以看到它?

于 2009-12-15T19:59:45.067 回答
0

我可以实现 MeasureOverride 和 ArrangeOvverride 类似:

    protected override Size MeasureOverride(Size availableSize)
    {
        foreach (var element in Children)
            element.Measure(availableSize);
        return base.MeasureOverride(availableSize);
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
        foreach (var element in Children)
        {
            var left = GetLeft(element);
            var top = GetTop(element);
            var size = element.DesiredSize;
            element.Arrange(
                new Rect(left, top, size.Width, size.Height)
                );
        }
        return base.ArrangeOverride(finalSize);
    }

在我的 MyCanvas 使用示例中,我可以按预期查看黑色矩形。

但是 Canvas 没有实现这些方法。它是如何工作的?!

于 2009-12-16T10:40:28.553 回答