Silverlight Canvas:它是如何工作的?

发布于 2024-08-14 16:05:54 字数 2013 浏览 7 评论 0原文

在 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>

In silverlight Canvas class (with Reflector) has very simple implementation: 3 attached dependency properties (Left, Top, ZIndex) and 2 ovverides of MeasureOverride and ArrangeOverride methods which do nothing special.

But if i use my implementation like:

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

And then use MyCanvas in XAML like standard Canvas.
That's not working as expected (i see the empty screen).

How Canvas was implemented?

--
Additional code:
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));
}

Used in XAML like:

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

if change MyCanvas to standard Canvas, i can view black-filled rectangle at position 10,10.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

欢烬 2024-08-21 16:05:54

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

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

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

This seems to be a bug in the Silverlight disassembling engine of Reflector. You can build your own Silverlight Canvas control with the following steps:

  • Disassemble the WPF canvas control in Reflector and copy the code to Visual Studio.
  • Remove the DependencyProperties Bottom and Right, as well as their Get and Set methods.
  • Remove the Bottom and Right clauses from ArrangeOverride.
  • Replace FrameworkPropertyMetadata by PropertyMetadata.
  • Remove the property validation arguments from the DependencyProperty initialization.

Be aware that the Canvas created this way does not have a ZIndex property.

醉酒的小男人 2024-08-21 16:05:54

正如您所说,画布只不过是具有左侧和顶部附加属性的面板。根据 MSDN

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

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

Canvas is nothing more than a Panel with Left and Top attached properties, as you said. According to MSDN:

Defines an area within which you can
explicitly position child objects by
using coordinates that are relative to
the area.

That's it- a Canvas can have an explicit location inside another FrameworkElement-derived container. If you're not seeing your handrolled Canvas, you may have a rendering error. Have you tried changing the background color to make sure you can see it?

浪菊怪哟 2024-08-21 16:05:54

我可以实现 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并没有实现这些方法。它是如何运作的?

I can implement MeasureOverride and ArrangeOvverride something like:

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

And i can view black rectangle as expected in my example of MyCanvas usage.

But Canvas not implement these methods. How does it work?!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文