【问题标题】:How to make the canvas detect touch input properly in C#?如何使画布在 C# 中正确检测触摸输入?
【发布时间】:2014-02-07 07:23:04
【问题描述】:

基本上,我试图让画布监听触摸输入(点击),并增加屏幕上的点击次数。当我触摸设备上的屏幕时它不起作用。我调试了我的代码,除了没有检测到触摸之外,似乎没有什么异常。我检查了 ZIndex 并且画布在屏幕前面是可触摸的。如何让它发挥作用?

XAML:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" VerticalAlignment="Center" Margin="188,10,187,397"/>
        <Button Content="Reset" HorizontalAlignment="Stretch" Margin="-18,535,-18,0" VerticalAlignment="Top" Click="Button_Click"/>
        <Canvas ZIndex="0" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" MouseLeave="Canvas_MouseLeave"/>

</Grid>

C#:

int taps = 0; // create var to detect number of times, user touches the screen

    // Constructor
    public MainPage()
    {
        InitializeComponent();
    }

    // method to register the touch as the finger is placed on the screen
    private void Canvas_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        //Canvas c = sender as Canvas;
        counter.Text = "TOUCHED!";
    }

    //method register the touch as the finger is lifting up from the screen
    private void Canvas_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        //Canvas c = sender as Canvas;
        taps++;
        counter.Text = taps.ToString(); //convert var from int to string
    }

    //method register the touch as the finger leaves the area of the screen
    private void Canvas_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
    {
        //Canvas c = sender as Canvas;
        MessageBox.Show("You left the screen without lifting your finger. That does not count as a tap!", "Caution!", MessageBoxButton.OK);
    }

    // method to reset the counter to zero when button is pressed and released
    private void Button_Click(object sender, RoutedEventArgs e)
    {
        taps = 0; // reset the count
        counter.Text = taps.ToString(); // convert var from int to string
    }

【问题讨论】:

  • 你能在运行时获得事件的断点吗? (我的意思是说事件被解雇了吗?)
  • 是的,我在所有方法上都设置了一个断点,所有方法都没有被触发,除了 Button_Click 有效。
  • 好的,现在检查答案。

标签: c# xaml canvas windows-phone-8 visual-studio-2013


【解决方案1】:

我不知道你为什么要用Canvas 来做这件事 - 因为你在这个Canvas 中没有任何内容,所以它无法注册你的点击/点击,Canvas 也是hard to adjust to screen。我认为如果你想用 MouseUp/Down 来做,可以用更简单的方法来做——直接订阅包含你的元素的 Grid,而不是用额外的 Canvas 填充这个 Grid

在 XAML 中:

<Grid x:Name="ContentPanel"  Margin="12,0,12,0" Background="Transparent">
    <Grid.RowDefinitions>
       <RowDefinition Height="7*"/>
       <RowDefinition Height="1*"/>
       <RowDefinition Height="1*"/>
    </Grid.RowDefinitions>
    <TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" VerticalAlignment="Center" Grid.Row="0"/>
    <Button Content="Reset" HorizontalAlignment="Stretch" VerticalAlignment="Center" Click="Button_Click" Grid.Row="1"/>
    <TextBlock Name="Touched" FontSize="50" HorizontalAlignment="Center" TextWrapping="Wrap" Text="Touched" VerticalAlignment="Center" Visibility="Collapsed" Grid.Row="2"/>                
</Grid>

在后面的代码中:

private int taps = 0;
public MainPage()
{
    InitializeComponent();

    ContentPanel.MouseLeftButtonDown += ContentPanel_MouseLeftButtonDown;
    ContentPanel.MouseLeftButtonUp += ContentPanel_MouseLeftButtonUp;
}

private void ContentPanel_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
   taps++;
   counter.Text = taps.ToString(); //convert var from int to string
   Touched.Visibility = Visibility.Collapsed;
}

private void ContentPanel_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    Touched.Visibility = Visibility.Visible;
}

// method to reset the counter to zero when button is pressed and released
private void Button_Click(object sender, RoutedEventArgs e)
{
   taps = 0; // reset the count
   counter.Text = taps.ToString(); // convert var from int to string
}

如您所见,我已经订阅了 Grid 事件(覆盖整个屏幕) - 但为了使其工作,我必须将其背景画笔设置为透明,否则只有在您触摸文本时才会工作。

还有很多其他方法可以让您的应用正常运行,但我希望这会有所帮助。

【讨论】:

  • 它有效,但并不完美。虽然是进步。只有当我在包含数字的文本块内触摸时,它才会记录触摸。其次,每次我点击屏幕时,重置按钮都会摇晃,这会分散注意力。这两个问题有什么解决办法吗?
  • @TheAmazingKnight 正如我所写的 - 你是否将 Grid 的背景设置为透明?摇摇晃晃是什么意思?
  • 当我摆脱高度值为 7、1、1 的 Grid.RowDefinitions 时,它似乎修复了摇晃的重置按钮(略微上下移动)。关于透明,是的 LayoutRoot 和ContentPanel 设置为透明。
  • 我有一个问题,制作包含数字的文本块并简单地拖动它以覆盖整个屏幕,因为它现在填充了以前不可触摸的空白空间,这是否是正确的方法。
  • @TheAmazingKnight 欢迎您。如果您正在使用 VS,那么在 SolutionExplorer 窗口中打开 file.xaml(双击或右键单击 -> 打开)它应该打开设计器窗口。如果你只看到设计视图,那么在窗口的边界你应该找到一个按钮'XAML',它将切换到代码。我很高兴能帮上忙。祝你好运,编码愉快。
【解决方案2】:

你不使用触摸事件有什么原因吗? 您应该使用 TouchDown 和 TouchUp,而不是使用 MouseLeftButtonDown 和 MouseLeftButtonUp。

只有当您不处理触摸事件或操作事件时,它们才会映射到鼠标事件。根据我的触摸经验,单击也不总是映射到 MouseLeftButtonDown。据我所知,您也可以通过鼠标事件仅识别一根手指。当您想计算更多手指时,需要使用 TouchDown/TouchUp 事件。

【讨论】:

    【解决方案3】:

    问题在于网格的重叠样式

    所以要么制作网格行,要么在网格内定义一个堆栈面板,就像这样。

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <stackpanel>
                <TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" Margin="0,0,0,0"/>
                <Canvas ZIndex="0" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" MouseLeave="Canvas_MouseLeave"/>
                <Button Content="Reset" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Top" Click="Button_Click"/>
        </stackpanel>
    </Grid>
    

    立即尝试并检查。

    【讨论】:

    • 仍然无法正常工作,现在重置按钮不见了,我想它在后面。
    【解决方案4】:

    您应该设置 Background 属性。如果您不希望任何背景将其设置为透明:

    <Canvas ZIndex="99" Background="Transparent" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" Tapped="Canvas_CountMyTaps"/>
    

    (如果您希望画布位于顶部,请确保它的 ZIndex 大于它重叠的其他元素)

    如果未设置(默认值为 null),则元素不会捕获任何点击/点击等,就好像它们“落空”一样。

    另外,考虑使用Tapped 事件,它是一个“更高级别”的事件,将响应点击、手指轻敲、触控笔等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 2011-12-15
      • 2018-01-16
      • 1970-01-01
      • 1970-01-01
      • 2018-01-14
      相关资源
      最近更新 更多