Skip to main content

Microsoft Silverlight

Answered Question Unexpected behavior after ScaleTransformRSS Feed

(0)

rleclerc
rleclerc

Member

Member

10 points

15 Posts

Unexpected behavior after ScaleTransform

I have created a user control that has drag and drop mouse capabilities. To this I planned to add a minimize button which would downscale the control box with an annimation. Testing this I just reduce the scale by 50%. Before I click the minimize button drag and drop works perfectly, however, after I click the minimize button, subsequent mouse clicks on the usercontrol fail to register mouse click events. I can toggle the minimize button so that it returns to full scale, but even then mouse clicks on the control fail to register. Is there some magic property I need to set after scaling?

 Thanks,

RDL

vincracker
vincracker

Contributor

Contributor

3114 points

521 Posts

Re: Unexpected behavior after ScaleTransform

Without seeing your code it is hard to locate error, but I don't understand why make a control which is freely available, try this thread for Drag and Drop Model Popup window. 

rleclerc
rleclerc

Member

Member

10 points

15 Posts

Re: Unexpected behavior after ScaleTransform

Why add an external library that may give you less control over the UI and which bloats your XAP, when drag and drop can be implemented in a few lines of code which can be cut and pasted where you need it or implemented in a base class? Anyways, it still doesn't address the problem I am having, because I want to annimate the collapse by scaling the window as it moves toward a taskbar.

It is easy to rerpdice this bug  (feature?) with a simple example so I am sure the other libraries would have the problem as well

1. Create a new Silverlight Application called TestDragDropResize

2. Create a UserControl called MyWindow

3. Set its code behind to:

public partial class MyWindow: UserControl
{
        private bool isMouseCapture = false;
        private Point clickPosition;
        private bool minimized;

        public MyWindow()
        {
            InitializeComponent();
            SetupMouseHandlers();
        }


        public void SetupMouseHandlers()
        {
            this.LayoutRoot.MouseLeftButtonDown += (x, y) =>
            {
                this.LayoutRoot.CaptureMouse();
                clickPosition = y.GetPosition(LayoutRoot);
                this.LayoutRoot.CaptureMouse();
                isMouseCapture = true;
            };

           this.LayoutRoot.MouseLeftButtonUp += (x, y) =>
            {
                this.LayoutRoot.ReleaseMouseCapture();
                isMouseCapture = false;
            };

            this.LayoutRoot.MouseMove += (x, y) =>
            {
                if (isMouseCapture)
                {
                    this.layoutTranslateTransform.X = y.GetPosition(this).X - clickPosition.X;
                    this.layoutTranslateTransform.Y = y.GetPosition(this).Y - clickPosition.Y;
                }
            };
        }
       
        private void MinMaxButton_Click(object sender, RoutedEventArgs e)
        {
            if (false == minimized)
                (Resources["Minimize"] as Storyboard).Begin();
            else
                (Resources["Maximize"] as Storyboard).Begin();
            minimized = !minimized;
        }

}

4. And set its XAML to:

<UserControl x:Class="TestDragDropResize.MyWindow"
    xmlns="
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml" >
   

<UserControl.Resources>
        <Storyboard x:Name="Minimize">
            <DoubleAnimation x:Name="ScaleDownX" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Border.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" To="0.5" Duration="0:0:1" />
            <DoubleAnimation x:Name="ScaleDownY" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Border.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" To="0.5" Duration="0:0:1" />
        </Storyboard>

        <Storyboard x:Name="Maximize">
            <DoubleAnimation x:Name="ScaleUpX" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Border.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" To="1" Duration="0:0:1" />
            <DoubleAnimation x:Name="ScaleUpY" Storyboard.TargetName="LayoutRoot" Storyboard.TargetProperty="(Border.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" To="1" Duration="0:0:1" />
        </Storyboard>
    </UserControl.Resources>
   

<Grid x:Name="LayoutRoot" Background="Black" Width="100" Height="100">
        <Grid.RenderTransform>
            <TransformGroup>
                <ScaleTransform x:Name="layoutScaleTransform" ScaleX="1" ScaleY="1" />
                <SkewTransform />
                <RotateTransform />
                <TranslateTransform x:Name="layoutTranslateTransform" X="0" Y="0" />
            </TransformGroup>
        </Grid.RenderTransform>
        <Button x:Name="MinMax" Click="MinMaxButton_Click" Width="20" Height="20" />
    </Grid>

</UserControl>

5. Add the "MyWindow" to to Page.xaml

6. Compile and Run.

 

UI TEST: Click on the black square and drag it around in your browser (This is just a proof, ignore the jump on the mouse capture). This demonstrates that Drag and drop works. Now click the button which scales MyWindow in half. Try to drag and drop (It will fail, but shouldn't). Click the button again to scale the Window back to normal size. Try again to move the Window (It will fail but shouldn't). I've tried this with IE8 and Chrome.

Note that if you put a break point in the labda expression for mousemove after the resize, you will see that the event fires. However, MouseLeftButtonDown will no longer fire after the resize. Also it doesn't seem like it matters what kind of container you use for MyWindow.

rleclerc
rleclerc

Member

Member

10 points

15 Posts

Re: Re: Unexpected behavior after ScaleTransform

Did anyone find this issue as well? I may not be the cause but I am running Windows 7 RC and VS 2008.

vincracker
vincracker

Contributor

Contributor

3114 points

521 Posts

Answered Question

Re: Re: Re: Unexpected behavior after ScaleTransform

Yes, it is a bug. I don't know why this happens but I can reproduce it. One thing that you expected wrong here is the MouseLeftButtonDown being not fired after the scaling. I can see all the events fired even after the scaling and dragging. So we have some other problem. To resolve this I go around. I used storyboard created in code. Code will look like below.

public partial class MyWindow : UserControl
    {
        private bool isMouseCapture = false;
        private Point clickPosition;
        private bool minimized;
        public Storyboard s = new Storyboard();
        public static double counter;

        public MyWindow()
        {
            InitializeComponent();
            SetupMouseHandlers();

            s.Duration = TimeSpan.FromSeconds(0.05);
            s.Completed += (sender, e) =>
            {
                if ((layoutScaleTransform.ScaleX >= 0.5 && minimized) || (layoutScaleTransform.ScaleX <= 1 && !minimized))
                {
                    layoutScaleTransform.ScaleX += counter;
                    layoutScaleTransform.ScaleY += counter;
                    lblMsg.Text = "Storyboard";
                    s.Begin();
                }
            };
        }

        public void SetupMouseHandlers()
        {
            this.LayoutRoot.MouseLeftButtonDown += (x, y) =>
            {
                this.LayoutRoot.CaptureMouse();
                clickPosition = y.GetPosition(LayoutRoot);
                this.LayoutRoot.CaptureMouse();
                isMouseCapture = true;
                lblMsg.Text = "mouse captured";
            };

            this.LayoutRoot.MouseLeftButtonUp += (x, y) =>
            {
                this.LayoutRoot.ReleaseMouseCapture();
                isMouseCapture = false;
                lblMsg.Text = "mouse released";
            };
            this.LayoutRoot.MouseMove += (x, y) =>
            {
                if (isMouseCapture)
                {
                    this.layoutTranslateTransform.X = y.GetPosition(this).X - clickPosition.X;
                    this.layoutTranslateTransform.Y = y.GetPosition(this).Y - clickPosition.Y;
                    lblMsg.Text = y.GetPosition(this).X.ToString() + " " + y.GetPosition(this).Y.ToString();
                }
            };
        }

        private void MinMaxButton_Click(object sender, RoutedEventArgs e)
        {
            lblMsg.Text = Convert.ToString((int)layoutTranslateTransform.X) + " " + Convert.ToString((int)layoutTranslateTransform.Y);

            if (false == minimized)
                counter = -0.1;
            //(Resources["Minimize"] as Storyboard).Begin();
            else
                counter = 0.1;
            //(Resources["Maximize"] as Storyboard).Begin();
            s.Begin();
            minimized = !minimized;
        }
    }

This will work for sure. And if anyone know what happened in former code let us know the reason.

 

rleclerc
rleclerc

Member

Member

10 points

15 Posts

Re: Re: Re: Unexpected behavior after ScaleTransform

You are right, it is firing the MouseLeftButtonDown event in this "HelloBug" code example. It's too bad I overwrote the other code already.

Nice work around. You could also use a DispatcherTimer here since the Storyboard isn't really doing anything for you.

  • Unanswered Question
  • Answered Question
  • Announcement
Microsoft Communities