Silverlight 中使用 CaptureMouse() 进行事件冒泡

发布于 2024-11-16 19:31:19 字数 3618 浏览 1 评论 0原文

我正在 Silverlight 中编写一个窗口程序,这意味着弹出窗口的顶部栏有一个可拖动区域,并且在该可拖动区域内有一个用于关闭窗口的“X”。我的拖动函数有一个 capturemouse() 事件,当与发生的事件冒泡结合时,会阻​​止调用 close 函数。这是代码:

private void close_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e){
            pop.IsOpen = false;
            hasFocus = true;
        }

        private void topBar_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Border item = sender as Border;
            mouseY = e.GetPosition(null).Y;
            mouseX = e.GetPosition(null).X;
            draggable = true;
            item.CaptureMouse();

        }

        private void topBar_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if(draggable){
                double changeY = e.GetPosition(null).Y - mouseY;
                double changeX = e.GetPosition(null).X - mouseX;
                double top = changeY + (double)pop.GetValue(Canvas.TopProperty);
                double left = changeX + (double)pop.GetValue(Canvas.LeftProperty);
                if(top<0){
                    top = 0;
                }
                if(left<0){
                    left = 0;
                }
                if(left>670){
                    left = 670;
                }
                if(top>450){
                    top = 450;
                }
                pop.SetValue(Canvas.TopProperty, top);
                pop.SetValue(Canvas.LeftProperty, left);
                mouseY = e.GetPosition(null).Y;
                mouseX = e.GetPosition(null).X;
            }
        }

        private void topBar_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Border item = sender as Border;
            draggable = false;
            mouseY = -1;
            mouseX = -1;
            item.ReleaseMouseCapture();
        }

编辑:这是整个弹出窗口的 XAML:

<Popup x:Name="pop" Height="200" Width="200" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Border CornerRadius="5" Width="200" Height="200" Background="#FFFAFCFF" BorderThickness="1">
                        <Border.BorderBrush>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#99666666" Offset="0" />
                                <GradientStop Color="#99F5F5F5" Offset="0.5"/>
                                <GradientStop Color="#99666666" Offset="1"/>
                            </LinearGradientBrush>
                        </Border.BorderBrush>
                        <StackPanel>
                            <Border x:Name="topBar" CornerRadius="4,4,0,0" BorderBrush="Silver" BorderThickness="0,0,0,1" Background="Crimson" Width="198" Height="20" MouseLeftButtonDown="topBar_MouseLeftButtonDown" MouseMove="topBar_MouseMove" MouseLeftButtonUp="topBar_MouseLeftButtonUp">
                                <Image x:Name="close" Source="X.png" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,7,0" Height="11" Width="11" MouseLeftButtonUp="close_MouseLeftButtonUp" />
                            </Border>
                            <StackPanel Margin="10">
                                <TextBlock Text="Printer info goes here..." />
                            </StackPanel>
                        </StackPanel>
                    </Border>
                </Popup>

I'm writing a window program in Silverlight, meaning that the top bar of a popup has a draggable area, and within that draggable area, an "X" that closes the window. My drag function has a capturemouse() event which, when combined with the event bubbling that occurs, prevents the close function from being called. Here's the code:

private void close_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e){
            pop.IsOpen = false;
            hasFocus = true;
        }

        private void topBar_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Border item = sender as Border;
            mouseY = e.GetPosition(null).Y;
            mouseX = e.GetPosition(null).X;
            draggable = true;
            item.CaptureMouse();

        }

        private void topBar_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
        {
            if(draggable){
                double changeY = e.GetPosition(null).Y - mouseY;
                double changeX = e.GetPosition(null).X - mouseX;
                double top = changeY + (double)pop.GetValue(Canvas.TopProperty);
                double left = changeX + (double)pop.GetValue(Canvas.LeftProperty);
                if(top<0){
                    top = 0;
                }
                if(left<0){
                    left = 0;
                }
                if(left>670){
                    left = 670;
                }
                if(top>450){
                    top = 450;
                }
                pop.SetValue(Canvas.TopProperty, top);
                pop.SetValue(Canvas.LeftProperty, left);
                mouseY = e.GetPosition(null).Y;
                mouseX = e.GetPosition(null).X;
            }
        }

        private void topBar_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
        {
            Border item = sender as Border;
            draggable = false;
            mouseY = -1;
            mouseX = -1;
            item.ReleaseMouseCapture();
        }

EDIT: here is the XAML for the entire popup:

<Popup x:Name="pop" Height="200" Width="200" VerticalAlignment="Center" HorizontalAlignment="Center">
                    <Border CornerRadius="5" Width="200" Height="200" Background="#FFFAFCFF" BorderThickness="1">
                        <Border.BorderBrush>
                            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                <GradientStop Color="#99666666" Offset="0" />
                                <GradientStop Color="#99F5F5F5" Offset="0.5"/>
                                <GradientStop Color="#99666666" Offset="1"/>
                            </LinearGradientBrush>
                        </Border.BorderBrush>
                        <StackPanel>
                            <Border x:Name="topBar" CornerRadius="4,4,0,0" BorderBrush="Silver" BorderThickness="0,0,0,1" Background="Crimson" Width="198" Height="20" MouseLeftButtonDown="topBar_MouseLeftButtonDown" MouseMove="topBar_MouseMove" MouseLeftButtonUp="topBar_MouseLeftButtonUp">
                                <Image x:Name="close" Source="X.png" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,7,0" Height="11" Width="11" MouseLeftButtonUp="close_MouseLeftButtonUp" />
                            </Border>
                            <StackPanel Margin="10">
                                <TextBlock Text="Printer info goes here..." />
                            </StackPanel>
                        </StackPanel>
                    </Border>
                </Popup>

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

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

发布评论

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

评论(1

尐偏执 2024-11-23 19:31:19

出现此问题的原因是您的 MouseCapture 调用。当您设置 mousecapture 时,边框是唯一允许启动鼠标事件的控件。这意味着当鼠标按钮按下时,图像不再触发鼠标事件。
如果没有鼠标捕获,它应该可以正常工作。只是出于我的好奇,你为什么要设置和释放它?

我希望这有帮助。

编辑:

您可以获取 mouseEvent 的位置并查看它是否落在图像中:

        var x = e.GetPosition(close).X;
        var y = e.GetPosition(close).Y;
        if (0 <= x && x <= 11 && 0 <= y && y <= 11)
        {
            //do the close call
        }

我尚未测试此代码,但它应该接近您想要执行的操作。

The problem occurs because of your MouseCapture calls. When you set the mousecapture, the border is the only control that will be allowed to initiate mouse events. This means the image, while the mouse button is down, no longer triggers mouseevents.
Without the mousecapture it should work fine. Just for my curiosity, why do you set and release it?

I hope this helps.

Edit:

You can get the position of the mouseEvent and see if it falls in the image:

        var x = e.GetPosition(close).X;
        var y = e.GetPosition(close).Y;
        if (0 <= x && x <= 11 && 0 <= y && y <= 11)
        {
            //do the close call
        }

I haven't tested this code but it should be close to what you want to do.

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