如何停止使用触摸移动 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 和删除。
我在您发布的代码中遇到的第一个问题是 PreviewTouchDown
和 PreviewMouseDown
事件处理程序。代码将 point
设置为相对于 this
- Window
- 当你第一次拖动时没问题,但之后任何其他拖动尝试都会立即将项目向上移动到top/left角.
为了解决这个问题,我编辑了事件处理程序以将 point
设置为相对于 grid
,以便在后续拖动时拖动计算是正确的。
第二个问题是拖动时没有捕获鼠标或触摸设备,当拖动到 grid
的边缘附近时会导致拖动停止。捕获鼠标或触摸也会使拖动更加顺畅。
为了解决这个问题,我向 PreviewTouchDown
和 PreviewMouseDown
事件处理程序添加了鼠标和触摸捕获,并添加了释放捕获的 TouchUp
和 MouseUp
事件处理程序.
这是完整的更新代码:
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);
}
}
}
希望对您有所帮助。
当我尝试使用触摸移动文本块时遇到了一个问题,当我使用鼠标交互执行相同操作时不会出现闪烁问题。有人可以帮我吗?
如何解决这个闪烁问题?
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 和删除。
我在您发布的代码中遇到的第一个问题是 PreviewTouchDown
和 PreviewMouseDown
事件处理程序。代码将 point
设置为相对于 this
- Window
- 当你第一次拖动时没问题,但之后任何其他拖动尝试都会立即将项目向上移动到top/left角.
为了解决这个问题,我编辑了事件处理程序以将 point
设置为相对于 grid
,以便在后续拖动时拖动计算是正确的。
第二个问题是拖动时没有捕获鼠标或触摸设备,当拖动到 grid
的边缘附近时会导致拖动停止。捕获鼠标或触摸也会使拖动更加顺畅。
为了解决这个问题,我向 PreviewTouchDown
和 PreviewMouseDown
事件处理程序添加了鼠标和触摸捕获,并添加了释放捕获的 TouchUp
和 MouseUp
事件处理程序.
这是完整的更新代码:
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);
}
}
}
希望对您有所帮助。