如何停止使用触摸移动 UI 元素时出现的闪烁问题?

How to stop this flickering issue ,which occurs when the UI element is moved using touch?

当我尝试使用触摸移动文本块时遇到了一个问题,当我使用鼠标交互执行相同操作时不会出现闪烁问题。有人可以帮我吗?

如何解决这个闪烁问题?

  public partial class MainWindow: Window
  {
    Canvas can = new Canvas() { Background=Brushes.White};
    Grid grid = new Grid() { Height=150,Width=100,Background=Brushes.Yellow};
    TextBlock textBlock = new TextBlock() { Text = "TextBlock Text" ,FontWeight=FontWeights.Bold };
    Point point = new Point();
    public MainWindow()
    {
        InitializeComponent();
        grid.Children.Add(textBlock);
        can.Children.Add(grid);
        Canvas.SetLeft(grid, 0);
        Canvas.SetTop(grid, 0);
        textBlock.PreviewMouseDown += TextBlock_PreviewMouseDown;
        textBlock.PreviewTouchDown += TextBlock_PreviewTouchDown;
        can.PreviewMouseMove += Can_PreviewMouseMove;
        can.PreviewTouchMove += Can_PreviewTouchMove;
        m_grid.Children.Add(can);

    }

    private void TextBlock_PreviewTouchDown(object sender, TouchEventArgs e)
    {
        point = e.GetTouchPoint(this).Position;

    }

    private void TextBlock_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {

            point = e.GetPosition(this);
    }

    private void Can_PreviewTouchMove(object sender, TouchEventArgs e)
    {
        if (e.OriginalSource is TextBlock )
        {
            Canvas.SetLeft(grid, e.GetTouchPoint(this).Position.X - point.X);
            Canvas.SetTop(grid, e.GetTouchPoint(this).Position.Y - point.Y);
        }
    }


    private void Can_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        if(e.OriginalSource is TextBlock && e.LeftButton==MouseButtonState.Pressed&&e.StylusDevice==null)
        {
            Canvas.SetLeft(grid, e.GetPosition(this).X - point.X);
            Canvas.SetTop(grid, e.GetPosition(this).Y - point.Y);
        }
    }

}

我无法重现您遇到的闪烁,但我认为这可能是由于您实施了 drag/touch 和删除。

我在您发布的代码中遇到的第一个问题是 PreviewTouchDownPreviewMouseDown 事件处理程序。代码将 point 设置为相对于 this - Window - 当你第一次拖动时没问题,但之后任何其他拖动尝试都会立即将项目向上移动到top/left角.

为了解决这个问题,我编辑了事件处理程序以将 point 设置为相对于 grid,以便在后续拖动时拖动计算是正确的。

第二个问题是拖动时没有捕获鼠标或触摸设备,当拖动到 grid 的边缘附近时会导致拖动停止。捕获鼠标或触摸也会使拖动更加顺畅。

为了解决这个问题,我向 PreviewTouchDownPreviewMouseDown 事件处理程序添加了鼠标和触摸捕获,并添加了释放捕获的 TouchUpMouseUp 事件处理程序.

这是完整的更新代码:

public partial class MainWindow : Window
{
    private Canvas can = new Canvas() { Background = Brushes.White };
    private Grid grid = new Grid() { Height = 150, Width = 100, Background = Brushes.Yellow };
    private TextBlock textBlock = new TextBlock() { Text = "TextBlock Text", FontWeight = FontWeights.Bold };
    private Point point = new Point();

    public MainWindow()
    {
        InitializeComponent();
        grid.Children.Add(textBlock);
        can.Children.Add(grid);
        Canvas.SetLeft(grid, 0);
        Canvas.SetTop(grid, 0);
        textBlock.PreviewMouseDown += TextBlock_PreviewMouseDown;
        textBlock.PreviewTouchDown += TextBlock_PreviewTouchDown;
        textBlock.MouseUp += TextBlock_MouseUp;
        textBlock.TouchUp += TextBlock_TouchUp;
        can.PreviewMouseMove += Can_PreviewMouseMove;
        can.PreviewTouchMove += Can_PreviewTouchMove;
        RootGrid.Children.Add(can);
    }

    private void TextBlock_PreviewTouchDown(object sender, TouchEventArgs e)
    {
        point = e.GetTouchPoint(grid).Position;
        e.TouchDevice.Capture(textBlock);
    }

    private void TextBlock_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        point = e.GetPosition(grid);
        e.MouseDevice.Capture(textBlock);
    }

    private void TextBlock_TouchUp(object sender, TouchEventArgs e)
    {
        e.TouchDevice.Capture(null);
    }

    private void TextBlock_MouseUp(object sender, MouseButtonEventArgs e)
    {
        e.MouseDevice.Capture(null);
    }

    private void Can_PreviewTouchMove(object sender, TouchEventArgs e)
    {
        if (e.OriginalSource is TextBlock)
        {
            Canvas.SetLeft(grid, e.GetTouchPoint(this).Position.X - point.X);
            Canvas.SetTop(grid, e.GetTouchPoint(this).Position.Y - point.Y);
        }
    }

    private void Can_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        if (e.OriginalSource is TextBlock && e.LeftButton == MouseButtonState.Pressed && e.StylusDevice == null)
        {
            Canvas.SetLeft(grid, e.GetPosition(this).X - point.X);
            Canvas.SetTop(grid, e.GetPosition(this).Y - point.Y);
        }
    }
}

希望对您有所帮助。