【问题标题】:How to move a Grid Panel in WPF Window如何在 WPF 窗口中移动网格面板
【发布时间】:2015-11-24 06:06:33
【问题描述】:

嗨,

如何在 WPF 窗口内移动(拖动)网格面板?网格面板没有位置或位置或 X 和 Y 坐标属性。我所看到的只是使用鼠标将网格面板从其当前位置移动到新位置,以便显示“隐藏”在其下方的控件。

任何指针?

非常感谢。

【问题讨论】:

    标签: c# wpf grid move


    【解决方案1】:

    这里有一些代码示例可以帮助您入门:

    在 XAML 中:

    创建一个网格并在其上定义一个渲染变换:

    <Grid x:Name="grid" Background="Blue" 
          Width="100" Height="100" 
          MouseDown="Grid_MouseDown" MouseMove="Grid_MouseMove" MouseUp="Grid_MouseUp">
        <Grid.RenderTransform>
            <TranslateTransform x:Name="tt"/>
        </Grid.RenderTransform>
    </Grid>
    

    命名您希望网格在其中移动的控件:

    <Window x:Name="window" ...>
        <Grid x:Name="grid"...
    </Window>
    

    在后面的代码中:

    Point m_start;
    Vector m_startOffset;
    
    private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
    {
        m_start = e.GetPosition(window);
        m_startOffset = new Vector(tt.X, tt.Y);
        grid.CaptureMouse();
    }
    
    private void Grid_MouseMove(object sender, MouseEventArgs e)
    {
        if (grid.IsMouseCaptured)
        {
            Vector offset = Point.Subtract(e.GetPosition(window), m_start);
    
            tt.X = m_startOffset.X + offset.X;
            tt.Y = m_startOffset.Y + offset.Y;
        }
    }
    
    private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
    {
        grid.ReleaseMouseCapture();
    }
    

    【讨论】:

    • 不错,但是这种方法效率不高。当拖动包含大约 10 个自定义模板控件的网格时,我的 CPU 负载高达 23%! (Core i7 3770)没有更好的方法吗?我还将父容器改为canvas并使用Canvas.SetLeft,但性能没有变化。
    • 渲染转换很昂贵,尤其是当您动态地重新渲染一个非常复杂的控件时。没有简单的解决方法。一些建议:创建一个更简单的控件副本(甚至保存图像的快照)并将此副本用于拖放渲染转换。或者:不要在每次鼠标移动时更新渲染变换。每第 N 次点击更新它,或者仅当偏移量大于某个阈值时,或仅在定时间隔之后,等等。
    • 是的,我想我会检查用户的图形渲染层,并在系统不是第 2 层时移动控件的快照。
    • 我用这种方法实现了一次 3D 翻转视图,它真的很无缝。目前没有可用的代码,但这正是它所做的。将控件保存为图像,然后隐藏控件并显示图像。对图像执行所有变换,直到动画/操作完成,然后隐藏图像并再次显示实际控件,以便您可以与嵌套输入进行交互。
    【解决方案2】:

    基于 Josh G 的回答

    如果您想移动一个网格,Josh 的回答非常好,但缺少移动多个元素的功能。
    这是分别移动几个元素的方法

    XAML

    <Grid x:Name="gridHost">
        <Grid x:Name="gridBlue" Background="Blue" Width="100" Height="100" MouseDown="Grid_MouseDown" MouseMove="Grid_MouseMove" MouseUp="Grid_MouseUp" Margin="-100,0,0,0">
            <Grid.RenderTransform>
                <TranslateTransform/>
            </Grid.RenderTransform>
        </Grid>
        <Grid x:Name="gridRed" Background="Red" Width="100" Height="100" MouseDown="Grid_MouseDown" MouseMove="Grid_MouseMove" MouseUp="Grid_MouseUp" Margin="100,0,0,0">
            <Grid.RenderTransform>
                <TranslateTransform/>
            </Grid.RenderTransform>
        </Grid>
    </Grid>
    

    后面的代码

    Point m_start;
        Vector m_startOffset;
    
        private void Grid_MouseDown(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement element = sender as Grid;
            TranslateTransform translate = element.RenderTransform as TranslateTransform;
    
            m_start = e.GetPosition(gridHost);
            m_startOffset = new Vector(translate.X, translate.Y);
            element.CaptureMouse();
        }
    
        private void Grid_MouseMove(object sender, MouseEventArgs e)
        {
            FrameworkElement element = sender as Grid;
            TranslateTransform translate = element.RenderTransform as TranslateTransform;
    
            if (element.IsMouseCaptured)
            {
                Vector offset = Point.Subtract(e.GetPosition(gridHost), m_start);
    
                translate.X = m_startOffset.X + offset.X;
                translate.Y = m_startOffset.Y + offset.Y;
            }
        }
    
        private void Grid_MouseUp(object sender, MouseButtonEventArgs e)
        {
            FrameworkElement element = sender as Grid;
            element.ReleaseMouseCapture();
        }
    

    【讨论】:

      【解决方案3】:

      只需将网格面板放在画布内而不是直接放在窗口中 - 这将为其提供 X/Y 坐标。

      然后您可以使用自定义附加属性实现拖放行为,例如此处详述 (http://www.deepcode.co.uk/archive/2008/11/16/using-attached-properties-to-compose-new-behaviour.aspx)

      【讨论】:

        【解决方案4】:
            public void dragme(object sender, MouseButtonEventArgs e)
            {
                if (_Move.IsChecked == true)
                    db.Attach((DependencyObject)sender);
        

        }

        //// MouseDragElementBehavior 数据库;

         private void canvass_PreviewMouseDown(object sender, MouseButtonEventArgs e) 
            {
        if (_Move.IsChecked == true && filmgrid.Visibility == Visibility.Visible)// == true)  
                    {
                        filmgrid.PreviewMouseDown += new MouseButtonEventHandler(dragme); 
                    }
        

        }

        【讨论】:

          猜你喜欢
          • 2023-01-12
          • 1970-01-01
          • 2013-05-12
          • 2022-01-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多