views:

10

answers:

1

Ok,

So I have a situation, where an border is being scaled (sometimes by a large amount) and translated. Inside the border is a grid, and inside the grid are two images, one is a photo and is stretched to the size of the border, and the other, I intend on being an icon, which needs to be a fixed size in the bottom left hand corner.

The problem is, that I want to remove the effect scaling is having on the icon. This is because I've given the icon a fixed size and would like it to remain that size, but unfortunately the scaling from the border is propagating down the the children of the border and effecting them also.

So I've tried using an attached property, similar to this pixel snapping artical (http://blogs.msdn.com/b/devdave/archive/2008/06/22/using-an-attached-dependencyproperty-to-implement-pixel-snapping-as-an-attached-behavior.aspx), but it doesn't seem to make a difference. When steped through, the elements which are being modified in LayoutUpdate always seem to have the identity matrix for the render transform anyway, before I've set it.

I guess I'm miss-interperating how render transforms are applied to children maybe?

Anyway, this is what I have (Also, I know this (if it worked) would remove translation too, which isn't what I want!):

    public static readonly DependencyProperty IsConstantSizeProperty = 
        DependencyProperty.RegisterAttached(
        "ConstantWidth",
        typeof(bool),
        typeof(ItemsControlEX),
        new PropertyMetadata(new PropertyChangedCallback(IsConstantSizeChanged)));

    private static List<FrameworkElement> m_constSizeObjects = new List<FrameworkElement>();

    private static void IsConstantSizeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        bool isConstantWidth = (bool)args.NewValue;
        if (isConstantWidth)
        {
            FrameworkElement el = (FrameworkElement)obj;
            m_constSizeObjects.Add(el);

            el.LayoutUpdated += new EventHandler(el_LayoutUpdated);
            el.Unloaded += new RoutedEventHandler(el_Unloaded);
        }
    }

    static void el_Unloaded(object sender, RoutedEventArgs e)
    {
        FrameworkElement el = (FrameworkElement)sender;
        el.Unloaded -= new RoutedEventHandler(el_Unloaded);
        el.LayoutUpdated -= new EventHandler(el_LayoutUpdated);

        m_constSizeObjects.Remove(el);
    }

    static void el_LayoutUpdated(object sender, EventArgs e)
    {
        foreach (FrameworkElement el in m_constSizeObjects)
        {
            MatrixTransform trans = new MatrixTransform();
            trans.Matrix = Matrix.Identity;
            el.RenderTransform = trans;
        }
    }

    public static void SetIsConstantWidth(UIElement element, Boolean value)
    {
        element.SetValue(IsConstantSizeProperty, value);
    }

    public static Boolean GetIsConstantWidth(UIElement element)
    {
        return (Boolean)element.GetValue(IsConstantSizeProperty);
    }

I'm thinking I'm probably thinking about this in completely the wrong way maybe. I guess the sensible solution would be to refactor to remove the need for scaling, but I guess I was just after a quicker solution that I can use until I have time.

Any help is appreciated! :)

Thanks!

Andy.

A: 

If you are only scaling (I assume fixed aspect ratio) that seems overly complicated, why not place the photo in a ViewBox container? Place the ViewBox (containing the photo) and the icon (in that order) in a parent grid.

  • Make the icon relative to the bottom left using alignment and margin settings
  • Resize the viewbox to scale your image.

The grid will shrink to fit the viewbox size. The icon will remain relative to the grid bottom-left.

Your pixel snapping behaviour should work on a ViewBox.

If you need a specific example, please provide some of your Xaml to work from.

Enough already
Wow, forgot all about ViewBox! Its always the simple solutions that get overlooked! Either way I've removed the need for scalling so I've solved it that way! Quicker than I imaginged! :) Would still be interested in reading up in more depth about how transformations are propagated to children, just out of interest, if you have any knowledge/links?
Andy
@Andy: Unlike real 3D rendering, it effectively works from the bottom up. Just imagine each child control is just a bitmap. It then has the next transform applied to it by the parent. Rinse and repeat until you hit the top of the render tree :)
Enough already