Silverlight Canvas: как это работает? - PullRequest
3 голосов
/ 15 декабря 2009

В Silverlight класс Canvas (с Reflector) имеет очень простую реализацию: 3 прикрепленных свойства зависимостей (Left, Top, ZIndex) и 2 оверида методов MeasureOverride и ArrangeOverride, которые не делают ничего особенного.

Но если я использую свою реализацию как:

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

А затем используйте MyCanvas в XAML как стандартный Canvas. Это не работает, как ожидалось (я вижу пустой экран).

Как был реализован 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>

Ответы [ 3 ]

2 голосов
/ 26 июня 2010

Это, похоже, ошибка в движке разборки Silverlight в Reflector. Вы можете создать свой собственный элемент управления Silverlight Canvas, выполнив следующие действия:

  • Разберите элемент управления WPF canvas в Reflector и скопируйте код в Visual Studio.
  • Удалите DependencyProperties Bottom и Right, а также их методы Get и Set.
  • Удалить предложения Bottom и Right из ArrangeOverride.
  • Заменить FrameworkPropertyMetadata на PropertyMetadata.
  • Удалите аргументы проверки свойства из инициализации DependencyProperty.

Имейте в виду, что созданный таким образом Canvas не имеет свойства ZIndex.

0 голосов
/ 16 декабря 2009

Я могу реализовать 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 не реализует эти методы. Как это работает?!

0 голосов
/ 15 декабря 2009

Canvas - это не что иное, как Panel с прикрепленными свойствами Left и Top, как вы сказали. Согласно MSDN :

Определяет область, в которой вы можете явно позиционировать дочерние объекты используя координаты относительно площадь.

Вот и все - Canvas может иметь явное местоположение внутри другого контейнера, производного от FrameworkElement. Если вы не видите свой управляемый Canvas, у вас может быть ошибка рендеринга. Вы пытались изменить цвет фона, чтобы убедиться, что его видно?

...