none
UWPアプリの画面で、クリックされた位置を知る方法 RRS feed

  • 質問

  • UWPの画面上で、マウスの左クリックがあったとき、クリックされた位置(X座標、Y座標)を知る方法をご教示ください。

    <やりたいこと>

    StackPanelに(おそらく)画像を表示する。左記のStackPanel上にてクリックがあったとき、左記のどの画像がクリックされたかを判断し、それに基づいて動作する。※画像の位置や内容や数は決まっていない(UWPの画面を開くときに設定を読み込んで、その内容によって変化する)ためXAMLに書いておくことは不可です。

    2019年8月18日 21:52

回答

  • ナノレスさん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    下記のように、ルートコントロールの右クリックイベントをキャプチャしてください。

    <Grid x:Name="Root" RightTapped="Grid_RightTapped">
    
    </Grid>
    
    
      private void Grid_RightTapped(object sender, RightTappedRoutedEventArgs e)
            {
                Point ptrPt = e.GetPosition(Root);
                var x = ptrPt.X;
                var y = ptrPt.Y;
            }
    

    そして、x、yの結果はご希望のものです。

    どうぞよろしくお願いします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    • 回答としてマーク ナノレス 2019年8月26日 11:37
    2019年8月26日 7:32
    モデレータ

すべての返信

  • ナノレスさん、こんにちは。フォーラムオペレーターのHarukaです。
    MSDNフォーラムにご投稿くださいましてありがとうございます。

    下記のように、ルートコントロールの右クリックイベントをキャプチャしてください。

    <Grid x:Name="Root" RightTapped="Grid_RightTapped">
    
    </Grid>
    
    
      private void Grid_RightTapped(object sender, RightTappedRoutedEventArgs e)
            {
                Point ptrPt = e.GetPosition(Root);
                var x = ptrPt.X;
                var y = ptrPt.Y;
            }
    

    そして、x、yの結果はご希望のものです。

    どうぞよろしくお願いします。


    MSDN/ TechNet Community Support Haruka

    ~参考になった投稿には「回答としてマーク」をご設定ください。なかった場合は「回答としてマークされていない」も設定できます。同じ問題で後から参照した方が、情報を見つけやすくなりますので、
    ご協力くださいますようお願いいたします。また、MSDNサポートに賛辞や苦情がある場合は、MSDNFSF@microsoft.comまでお気軽にお問い合わせください。~

    • 回答としてマーク ナノレス 2019年8月26日 11:37
    2019年8月26日 7:32
    モデレータ
  • #フォーラムの不具合で返信できない不具合が出ていたのがようやく復旧したのね

    いちおうボタンを配置しておいてクリックイベントを取得して、そこから座標は計算できます

    <Page
        x:Class="App1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Content="追加" Click="AddButton_Click" Margin="10" />
    
            <ScrollViewer Grid.Row="1" >
                <!-- StackPanelの外側にButtonを置くパターン-->
                <Button Click="StackButton_Click" VerticalAlignment="Top">
                    <Button.Template>
                        <!-- ボタンに余計な装飾を持たせないようにする-->
                        <ControlTemplate TargetType="Button">
                            <ContentPresenter Content="{TemplateBinding Content}" />
                        </ControlTemplate>
                    </Button.Template>
    
                    <StackPanel x:Name="stack"/>
                </Button>
            </ScrollViewer>
        </Grid>
    </Page>
    Public NotInheritable Class MainPage
        Inherits Page
    
        Private Sub AddButton_Click(sender As Object, e As RoutedEventArgs)
            '追加ボタンをクリックする毎にStackPanelにImageを追加する。(ImageはBorderの中に)
    
            Dim border As New Border
            border.Width = 50
            border.Height = 50
    
            border.Background = New SolidColorBrush(Windows.UI.Colors.Transparent)
            border.BorderBrush = New SolidColorBrush(Windows.UI.Colors.Black)
            border.BorderThickness = New Thickness(1)
            border.Margin = New Thickness(5)
            border.Tag = "Image配置用"
    
            'Imageは追加するが今回は特に絵は入れない
            Dim img As New Image
            img.HorizontalAlignment = HorizontalAlignment.Stretch
            img.VerticalAlignment = VerticalAlignment.Stretch
            img.Stretch = Stretch.Fill
    
            border.Child = img
            border.Margin = New Thickness((New Random()).NextDouble() * 300, 2, 2, 2) '横位置がランダムになるように
    
            Me.stack.Children.Add(border)
    
        End Sub
    
        Private Sub StackButton_Click(sender As Object, e As RoutedEventArgs)
            'StackPaneのすぐ外側にあるボタンでClickを判定
    
            '現在のポインターの座標を取得
            'ただしタッチパネルなどで複数ポインタがある場合は対応できない
            Dim window = Windows.UI.Core.CoreWindow.GetForCurrentThread()
            Dim screenPoint As Point = window.PointerPosition 'スクリーン座標
            Dim x = screenPoint.X - window.Bounds.X
            Dim y = screenPoint.Y - window.Bounds.Y
    
            Dim point = New Point(x, y) 'Windowに対する座標
            Debug.WriteLine($"@{x},{y}")
    
            '座標に存在する要素をすべて取り出す
            Dim elements = VisualTreeHelper.FindElementsInHostCoordinates(point, Me).ToArray()
    
            For Each element As UIElement In elements
                If TypeOf element Is Border Then
                    Dim border = DirectCast(element, Border)
                    If border.Tag = "Image配置用" Then
                        '子要素はImageなのでやりたいことをする
                        'Dim img As Image = CType(border.Child, Image)
    
                        'テストなのでBorderの背景色を変更だけ
                        border.Background = GetRandomSolidBrush()
                        Return
                    End If
                End If
            Next
        End Sub
    
        Private Function GetRandomSolidBrush()
            Dim bs(3) As Byte
            Dim rnd As New System.Random()
            rnd.NextBytes(bs)
    
            Dim color = Windows.UI.ColorHelper.FromArgb(255, bs(1), bs(2), bs(3))
            Return New SolidColorBrush(color)
        End Function
    End Class
    

    それよりもStackPanelにボタンを配置して、そのボタンのクリックイベントを使ったほうが楽で確実です

    <Page
        x:Class="App1.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"
        Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Page.Resources>
            <!-- 余計な装飾の無いボタンのテンプレート-->
            <ControlTemplate x:Key="simpleButtonTemplate" TargetType="Button">
                <Border BorderBrush="Black" BorderThickness="1"
                        Background="{TemplateBinding Background}">
                    <ContentPresenter Content="{TemplateBinding Content}" />
                </Border>
            </ControlTemplate>
            
            <!-- StackPanelに配置するボタンのスタイル-->
            <Style x:Key="simpleButtonStyle" TargetType="Button">
                <Setter Property="Background" Value="Transparent" />
                <Setter Property="Width" Value="50" />
                <Setter Property="Height" Value="50" />
                <Setter Property="Template" Value="{StaticResource simpleButtonTemplate}" />
            </Style>
        </Page.Resources>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition />
            </Grid.RowDefinitions>
            <Button Content="追加" Click="AddButton_Click" Margin="10" />
    
            <ScrollViewer Grid.Row="1" >
                <StackPanel x:Name="stack"/>
            </ScrollViewer>
        </Grid>
    </Page>
    Public NotInheritable Class MainPage
        Inherits Page
    
        Private Sub AddButton_Click(sender As Object, e As RoutedEventArgs)
            '追加ボタンをクリックする毎にStackPanelにImageを追加する。(ImageはBorderの中に)
    
            Dim buttonStyle = DirectCast(Me.Resources("simpleButtonStyle"), Style) 'リソースで作ってあるボタンのスタイル
    
            Dim button As New Button
            button.Style = buttonStyle
            button.Margin = New Thickness((New Random()).NextDouble() * 300, 2, 2, 2) '横位置がランダムになるように
    
    
            'Imageは追加するが今回は特に絵は入れない
            Dim img As New Image
            img.HorizontalAlignment = HorizontalAlignment.Stretch
            img.VerticalAlignment = VerticalAlignment.Stretch
            img.Stretch = Stretch.Fill
    
            button.Content = img
    
            'ボタンのクリックイベントを登録
            AddHandler button.Click, AddressOf StackButton_Click
    
            Me.stack.Children.Add(button)
        End Sub
    
        Private Sub StackButton_Click(sender As Object, e As RoutedEventArgs)
            'StackPaneの要素に追加したボタンでClickを判定
    
            Dim button As Button = DirectCast(sender, Button)
            Dim img As Image = DirectCast(button.Content, Image) 'ContentはImageなのでやりたいことをする
    
    
            'テストなのでBorderの背景色を変更だけ
            button.Background = GetRandomSolidBrush()
        End Sub
    
        Private Function GetRandomSolidBrush()
            Dim bs(3) As Byte
            Dim rnd As New System.Random()
            rnd.NextBytes(bs)
    
            Dim color = Windows.UI.ColorHelper.FromArgb(255, bs(1), bs(2), bs(3))
            Return New SolidColorBrush(color)
        End Function
    End Class

    個別に明示されていない限りgekkaがフォーラムに投稿したコードにはフォーラム使用条件に基づき「MICROSOFT LIMITED PUBLIC LICENSE」が適用されます。(かなり自由に使ってOK!)

    2019年8月26日 9:25