检测手悬停在KinectTileButton上

时间:2013-12-13 08:39:15

标签: c# wpf hover kinect

我正在用kinect和arduino做一个“简单”的项目,但我找不到这样做。

我正试图在手悬停KinectTileButton时触发一个函数,而不是鼠标。

到目前为止我的代码:

<Window x:Class="KINECT_WPF_TEST_1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:k="http://schemas.microsoft.com/kinect/2013"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="clr-namespace:Microsoft.Samples.Kinect.ControlsBasics"
    Name="ControldelRobot"
    Title="Control del Robot con Kinect" Height="700" Width="1350"
    FontFamily="Segoe UI"
    Closing="WindowClosing"
    >

<Grid>
    <Grid Grid.Row="0"  Margin="10 0 10 20" Grid.ColumnSpan="2">
    <!--<Image HorizontalAlignment="Left" VerticalAlignment="Bottom" Source="Images\Logo.png" Stretch="None" Margin="0 0 0 4"/>-->
    <k:KinectUserViewer k:KinectRegion.KinectRegion="{Binding ElementName=kinectRegion}" Height="100" Margin="1232,275,0,275" />
    <k:KinectSensorChooserUI HorizontalAlignment="Center" VerticalAlignment="Top" Name="sensorChooserUi" />
    <!--<TextBlock HorizontalAlignment="Right" Margin="0 0 -1 0" VerticalAlignment="Bottom" Foreground="{StaticResource MediumGreyBrush}" FontSize="18">Controls Basics</TextBlock>-->
</Grid>

    <k:KinectRegion HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="650" Width="1252" x:Name="kinectRegion">
        <Grid Height="650" Width="1252" x:Name="kinectRegionGrid">

            <WrapPanel HorizontalAlignment="Left" Height="630" Margin="10,10,0,0" VerticalAlignment="Top" Width="1232" >
                <k:KinectTileButton Background="LightSkyBlue"  Label="Codo Arriba" Width="410" Height="210" />
                <k:KinectTileButton Label="Girar Derecha" Width="410" Height="210"/>
                <k:KinectTileButton Label="Pinza Abre" Width="410" Height="210"/>
                <k:KinectTileButton Label="Hombro Subir" Width="175" Height="210" FontSize="24"/>
                <k:KinectTileButton k:KinectTileButton.MouseEnter="KinectTileButtonEnter" k:KinectTileButton.MouseLeave="KinectTileButtonLeave"  Label="Paro" Width="175" Height="210" FontSize="24"/>
                <k:KinectTileButton Label="Hombro Bajar" Width="175" Height="210" FontSize="24"/>
                <k:KinectTileButton k:KinectTileButton.MouseEnter="KinectTileButtonEnter" k:KinectTileButton.MouseLeave="KinectTileButtonLeave"  Label="Paro" Width="175" Height="210" FontSize="24"/>
                <k:KinectTileButton Label="Muñeca Abajo" Width="175" Height="210" FontSize="24"/>
                <k:KinectTileButton k:KinectTileButton.MouseEnter="KinectTileButtonEnter" k:KinectTileButton.MouseLeave="KinectTileButtonLeave"  Label="Paro" Width="175" Height="210" FontSize="24"/>
                <k:KinectTileButton Label="Muñeca Arriba" Width="175" Height="210" FontSize="24"/>
                <k:KinectTileButton k:KinectTileButton.MouseEnter="KinectTileButtonEnter" k:KinectTileButton.MouseLeave="KinectTileButtonLeave"  Label="Codo Abajo" Width="410" Height="210"/>
                <k:KinectTileButton Label="Girar Izquierda" Width="410" Height="210"/>
                <k:KinectTileButton Label="Pinza Cierra" Width="410" Height="210"/>
            </WrapPanel>
        </Grid>
    </k:KinectRegion>
</Grid>

CS:

using Microsoft.Kinect;
using Microsoft.Kinect.Toolkit;
using Microsoft.Kinect.Toolkit.Controls;

using System.IO.Ports;
using System.Management;




namespace KINECT_WPF_TEST_1
{
/// <summary>
/// Lógica de interacción para MainWindow.xaml
/// </summary>
public partial class MainWindow
{
    private readonly KinectSensorChooser sensorChooser;

    private SerialPort conexionArduino = new SerialPort();

    public MainWindow()
    {
        InitializeComponent();

        // initialize the sensor chooser and UI
        sensorChooser = new KinectSensorChooser();
        sensorChooser.KinectChanged += SensorChooserOnKinectChanged;
        sensorChooserUi.KinectSensorChooser = sensorChooser;
        sensorChooser.Start();

        // Bind the sensor chooser's current sensor to the KinectRegion
        var regionSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
        BindingOperations.SetBinding(kinectRegion, KinectRegion.KinectSensorProperty, regionSensorBinding);

        conexionArduino.BaudRate = 9600;
        string nombrePuerto = "";
        MessageBoxButton botones = MessageBoxButton.OKCancel;

        nombrePuerto = puertoArduino();

        while (nombrePuerto == null)
        {
            MessageBox.Show("Dispositivo no Enlazado", "Error", botones);
            nombrePuerto = puertoArduino();
        }


        conexionArduino.PortName = nombrePuerto;

    }

    private static void SensorChooserOnKinectChanged(object sender, KinectChangedEventArgs args)
    {
        if (args.OldSensor != null)
        {
            try
            {
                args.OldSensor.DepthStream.Range = DepthRange.Default;
                args.OldSensor.SkeletonStream.EnableTrackingInNearRange = false;
                args.OldSensor.DepthStream.Disable();
                args.OldSensor.SkeletonStream.Disable();
            }
            catch (InvalidOperationException)
            {
                // KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
                // E.g.: sensor might be abruptly unplugged.
            }
        }

        if (args.NewSensor != null)
        {
            try
            {
                args.NewSensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
                args.NewSensor.SkeletonStream.Enable();

                try
                {
                    args.NewSensor.DepthStream.Range = DepthRange.Near;
                    args.NewSensor.SkeletonStream.EnableTrackingInNearRange = true;
                }
                catch (InvalidOperationException)
                {
                    // Non Kinect for Windows devices do not support Near mode, so reset back to default mode.
                    args.NewSensor.DepthStream.Range = DepthRange.Default;
                    args.NewSensor.SkeletonStream.EnableTrackingInNearRange = false;
                }
            }
            catch (InvalidOperationException)
            {
                // KinectSensor might enter an invalid state while enabling/disabling streams or stream features.
                // E.g.: sensor might be abruptly unplugged.
            }
        }
    }


    private void enviarArduino(int numero)
    {
        byte[] xp = { 0x0, 0x0, 0x0, 0x0 };

        xp = BitConverter.GetBytes(numero);


        if (!conexionArduino.IsOpen)
            conexionArduino.Open();

        conexionArduino.Write("S");

        conexionArduino.Write(xp, 0, 4);
    }

    private void KinectTileButtonEnter(object sender, RoutedEventArgs e)
    {
        var button = (KinectTileButton)e.OriginalSource;
        string botonAplanado = button.Label as string;
        //var selectionDisplay = new SelectionDisplay(button.Label as string);

        switch (botonAplanado)
        {
            case "Codo Arriba":
                //MessageBox.Show(botonAplanado);
                enviarArduino(1);
                break;
            case "Codo Abajo":
                //MessageBox.Show(botonAplanado);
                enviarArduino(0);
                break;
            case "Pinza Abre":
                MessageBox.Show(botonAplanado);
                break;
            case "Pinza Cierra":
                MessageBox.Show(botonAplanado);
                break;
            case "Paro":
                //MessageBox.Show(botonAplanado);   
                enviarArduino(2);
                break;
            case "Hombro Subir":
                MessageBox.Show(botonAplanado);
                break;
            case "Hombro Bajar":
                MessageBox.Show(botonAplanado);
                break;
            case "Muñeca Abajo":
                MessageBox.Show(botonAplanado);
                break;
            case "Muñeca Arriba":
                MessageBox.Show(botonAplanado);
                break;
            case "Girar Izquierda":
                MessageBox.Show(botonAplanado);
                break;
            case "Girar Derecha":
                MessageBox.Show(botonAplanado);
                break;
        }
        //this.kinectRegionGrid.Children.Add(selectionDisplay);
        e.Handled = true;
    }

    private void KinectTileButtonLeave(object sender, RoutedEventArgs e)
    {
        enviarArduino(2);
        e.Handled = true;
    }

    private void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
    {
        enviarArduino(2);
        this.sensorChooser.Stop();
    }

    private string puertoArduino()
    {
        ManagementScope connectionScope = new ManagementScope();
        SelectQuery serialQuery = new SelectQuery("SELECT * FROM Win32_SerialPort");
        ManagementObjectSearcher searcher = new ManagementObjectSearcher(connectionScope, serialQuery);

        try
        {
            foreach (ManagementObject item in searcher.Get())
            {
                string desc = item["Description"].ToString();
                string deviceId = item["DeviceID"].ToString();

                if (desc.Contains("Arduino"))
                {
                    return deviceId;
                }
            }
        }
        catch (ManagementException e)
        {
            MessageBox.Show(e.Message.ToString());
        }

        return null;
    }
}

}

如果我使用MouseEnter和MouseLeave事件,它可以工作,但对于这个项目的propouse,我必须使用kinect。此外,点击事件有效,但这不是我需要的。

1 个答案:

答案 0 :(得分:0)

使用Kinect SDK Samples中的ControlBasics,我发现悬停的推荐者有一个按钮。

<local:KinectHoverButton Grid.Column="0" Style="{StaticResource KinectHoverButtonScrollLeftStyle}" Click="PageLeftButtonClick" IsEnabled="{Binding ElementName=ControlsBasicsWindow, Path=PageLeftEnabled}"/>

使用此按钮时,当您将鼠标悬停时,click事件将起作用。