我已经以编程方式创建了一个按钮,并将其传递给了一个listbutton
我正在尝试使用悬停方法来处理它,但它不起作用。当我手动制作按钮并通过按钮列表时,它可以正常工作。
设计
<Window x:Class="KinectButton.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Controls="clr-namespace:Coding4Fun.Kinect.Wpf.Controls;assembly=Coding4Fun.Kinect.Wpf"
Title="MainWindow" Height="700" Width="1000" Background="#FFAD4747" Loaded="Window_Loaded">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="261*" />
<ColumnDefinition Width="717*" />
</Grid.ColumnDefinitions>
<Canvas Background="#FF371780" Name="canvas" Grid.ColumnSpan="2">
<Controls:HoverButton Margin="0" Padding="0" x:Name="kinectButton" ImageSize="50"
ImageSource="/Images/RightHand.png"
ActiveImageSource="/Images/RightHand.png"
TimeInterval="2000" Panel.ZIndex="1000" Canvas.Left="0" Canvas.Top="0" />
<Button x:Name="button1" Content="Button1" Height="152" Canvas.Left="128" Canvas.Top="162" Width="320" Background="#FF64C02F" FontSize="53.333" Click="button1_Click" BorderThickness="4" Foreground="White" />
<Button x:Name="button2" Content="Button2" Height="152" Canvas.Left="514" Canvas.Top="162" Width="320" Background="#FFFFF600" FontSize="53.333" Click="button2_Click" BorderThickness="4" Foreground="Black" />
<Label Canvas.Left="322" Canvas.Top="34" Content="Kinect Buttons Demo" Height="58" Name="label1" FontSize="28" Width="302" Foreground="White" />
<Label Canvas.Left="38" Canvas.Top="524" Content="" Height="66" Name="message" Width="530" Foreground="White" FontSize="40" />
<Button Canvas.Left="804" Canvas.Top="23" Content="Quit" Height="91" Name="quitButton" Width="137" FontSize="28" Background="#FFFF3838" Foreground="White" Click="quitButton_Click" />
<Controls:HoverButton ActiveImageSource="/Images/RightHand.png" Canvas.Left="71" Canvas.Top="6" ImageSize="50" ImageSource="/Images/RightHand.png" Name="kinectButton2" Padding="0" Panel.ZIndex="1000" TimeInterval="2000" />
<StackPanel Height="621" Name="stackPanel1" Width="935" Canvas.Left="71" Canvas.Top="70" />
</Canvas>
<Image Height="128" HorizontalAlignment="Left" Margin="489,500,0,0" Name="videoStream" Stretch="Fill" VerticalAlignment="Top" Width="191" Grid.Column="1" />
</Grid>
</Window>
代码:
namespace KinectButton
{
public partial class MainWindow : Window
{
System.Windows.Controls.Button newBtn = new Button();
private KinectSensor _Kinect;
private WriteableBitmap _ColorImageBitmap;
private Int32Rect _ColorImageBitmapRect;
private int _ColorImageStride;
private Skeleton[] FrameSkeletons;
List<Button> buttons;
static Button selected;
float handX;
float handY;
float handX2;
float handY2;
public MainWindow()
{
InitializeComponent();
InitializeButtons();
kinectButton.Click += new RoutedEventHandler(kinectButton_Click);
this.Loaded += (s, e) => { DiscoverKinectSensor(); };
this.Unloaded += (s, e) => { this.Kinect = null; };
}
private void InitializeButtons()
{
newBtn.Content = "Hello";
newBtn.Width = 500;
newBtn.Height = 500;
newBtn.Click += new RoutedEventHandler(newBtn_Click);
buttons = new List<Button> { button1, button2, quitButton,newBtn};
}
private void DiscoverKinectSensor()
{
KinectSensor.KinectSensors.StatusChanged += KinectSensors_StatusChanged;
this.Kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
}
private void KinectSensors_StatusChanged(object sender, StatusChangedEventArgs e)
{
switch (e.Status)
{
case KinectStatus.Connected:
if (this.Kinect == null)
{
this.Kinect = e.Sensor;
}
break;
case KinectStatus.Disconnected:
if (this.Kinect == e.Sensor)
{
this.Kinect = null;
this.Kinect = KinectSensor.KinectSensors.FirstOrDefault(x => x.Status == KinectStatus.Connected);
if (this.Kinect == null)
{
MessageBox.Show("Sensor Disconnected. Please reconnect to continue.");
}
}
break;
}
}
public KinectSensor Kinect
{
get { return this._Kinect; }
set
{
if (this._Kinect != value)
{
if (this._Kinect != null)
{
UninitializeKinectSensor(this._Kinect);
this._Kinect = null;
}
if (value != null && value.Status == KinectStatus.Connected)
{
this._Kinect = value;
InitializeKinectSensor(this._Kinect);
}
}
}
}
private void UninitializeKinectSensor(KinectSensor kinectSensor)
{
if (kinectSensor != null)
{
kinectSensor.Stop();
kinectSensor.ColorFrameReady -= Kinect_ColorFrameReady;
kinectSensor.SkeletonFrameReady -= Kinect_SkeletonFrameReady;
}
}
private void InitializeKinectSensor(KinectSensor kinectSensor)
{
if (kinectSensor != null)
{
ColorImageStream colorStream = kinectSensor.ColorStream;
colorStream.Enable();
this._ColorImageBitmap = new WriteableBitmap(colorStream.FrameWidth, colorStream.FrameHeight,
96, 96, PixelFormats.Bgr32, null);
this._ColorImageBitmapRect = new Int32Rect(0, 0, colorStream.FrameWidth, colorStream.FrameHeight);
this._ColorImageStride = colorStream.FrameWidth * colorStream.FrameBytesPerPixel;
videoStream.Source = this._ColorImageBitmap;
kinectSensor.SkeletonStream.Enable(new TransformSmoothParameters()
{
Correction = 0.5f,
JitterRadius = 0.05f,
MaxDeviationRadius = 0.04f,
Smoothing = 0.5f
});
kinectSensor.SkeletonFrameReady += Kinect_SkeletonFrameReady;
kinectSensor.ColorFrameReady += Kinect_ColorFrameReady;
kinectSensor.Start();
this.FrameSkeletons = new Skeleton[this.Kinect.SkeletonStream.FrameSkeletonArrayLength];
}
}
private void Kinect_ColorFrameReady(object sender, ColorImageFrameReadyEventArgs e)
{
using (ColorImageFrame frame = e.OpenColorImageFrame())
{
if (frame != null)
{
byte[] pixelData = new byte[frame.PixelDataLength];
frame.CopyPixelDataTo(pixelData);
this._ColorImageBitmap.WritePixels(this._ColorImageBitmapRect, pixelData, this._ColorImageStride, 0);
}
}
}
private void Kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
using (SkeletonFrame frame = e.OpenSkeletonFrame())
{
if (frame != null)
{
frame.CopySkeletonDataTo(this.FrameSkeletons);
Skeleton skeleton = GetPrimarySkeleton(this.FrameSkeletons);
if (skeleton == null)
{
kinectButton.Visibility = Visibility.Collapsed;
}
else
{
Joint primaryHand = GetPrimaryHand(skeleton);
TrackHand(primaryHand);
}
}
}
}
//track and display hand
private void TrackHand(Joint hand)
{
if (hand.TrackingState == JointTrackingState.NotTracked)
{
kinectButton.Visibility = System.Windows.Visibility.Collapsed;
}
else
{
kinectButton.Visibility = System.Windows.Visibility.Visible;
DepthImagePoint point = this.Kinect.MapSkeletonPointToDepth(hand.Position, DepthImageFormat.Resolution640x480Fps30);
handX = (int)((point.X * LayoutRoot.ActualWidth / this.Kinect.DepthStream.FrameWidth) - (kinectButton.ActualWidth / 2.0));
handY = (int)((point.Y * LayoutRoot.ActualHeight / this.Kinect.DepthStream.FrameHeight) - (kinectButton.ActualHeight / 2.0));
handX2 = (int)((point.X * LayoutRoot.ActualWidth / this.Kinect.DepthStream.FrameWidth) - (kinectButton2.ActualWidth / 2.0));
handY2 = (int)((point.Y * LayoutRoot.ActualHeight / this.Kinect.DepthStream.FrameHeight) - (kinectButton2.ActualHeight / 2.0));
Canvas.SetLeft(kinectButton, handX);
Canvas.SetTop(kinectButton, handY);
Canvas.SetLeft(kinectButton2, handX2);
Canvas.SetTop(kinectButton2, handY2);
if (isHandOver(kinectButton, buttons)) kinectButton.Hovering();
else kinectButton.Release();
kinectButton.ImageSource = "/Images/RightHand.png";
kinectButton.ActiveImageSource = "/Images/RightHand.png";
kinectButton.ImageSource = "/Images/LeftHand.png";
kinectButton.ActiveImageSource = "/Images/LeftHand.png";
}
}
//detect if hand is overlapping over any button
private bool isHandOver(FrameworkElement hand, List<Button> buttonslist)
{
var handTopLeft = new Point(Canvas.GetLeft(hand), Canvas.GetTop(hand));
var handX = handTopLeft.X + hand.ActualWidth / 2;
var handY = handTopLeft.Y + hand.ActualHeight / 2;
foreach (Button target in buttonslist)
{
Point targetTopLeft = new Point(Canvas.GetLeft(target), Canvas.GetTop(target));
if (handX > targetTopLeft.X &&
handX < targetTopLeft.X + target.Width &&
handY > targetTopLeft.Y &&
handY < targetTopLeft.Y + target.Height)
{
selected = target;
return true;
}
}
return false;
}
//get the hand closest to the Kinect sensor
private static Joint GetPrimaryHand(Skeleton skeleton)
{
Joint primaryHand = new Joint();
if (skeleton != null)
{
primaryHand = skeleton.Joints[JointType.HandLeft];
Joint rightHand = skeleton.Joints[JointType.HandRight];
if (rightHand.TrackingState != JointTrackingState.NotTracked)
{
if (primaryHand.TrackingState == JointTrackingState.NotTracked)
{
primaryHand = rightHand;
}
else
{
if (primaryHand.Position.Z > rightHand.Position.Z)
{
primaryHand = rightHand;
}
}
}
}
return primaryHand;
}
//get the skeleton closest to the Kinect sensor
private static Skeleton GetPrimarySkeleton(Skeleton[] skeletons)
{
Skeleton skeleton = null;
if (skeletons != null)
{
for (int i = 0; i < skeletons.Length; i++)
{
if (skeletons[i].TrackingState == SkeletonTrackingState.Tracked)
{
if (skeleton == null)
{
skeleton = skeletons[i];
}
else
{
if (skeleton.Position.Z > skeletons[i].Position.Z)
{
skeleton = skeletons[i];
}
}
}
}
}
return skeleton;
}
void newButton_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Yay");
}
void kinectButton_Click(object sender, RoutedEventArgs e)
{
selected.RaiseEvent(new RoutedEventArgs(Button.ClickEvent, selected));
}
private void newBtn_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("hey");
}
private void button2_Click(object sender, RoutedEventArgs e)
{
message.Content = "Button 2 clicked!";
Window w = new Window();
Button b = new Button();
b.Content = "Button A";
canvas.Children.Add(newBtn);
// stackPanel1.Children.Add(newBtn);
stackPanel1.Children.Remove((UIElement)this.FindName("Button0"));
}
}
}
答案 0 :(得分:0)
以下代码会在代码中重新创建您的第一个按钮:
Button btn = new Button
{
Name = "button1",
Content = "Button1",
Height = 152,
Width = 320,
Foreground = "#FF64C02F",
FontSize = 53.333,
BorderThickness = 4
};
btn.Click += button1_Click;
canvas.Children.Add(btn);
Canvas.SetLeft(btn, 128);
Canvas.SetTop(btn, 162);
那说...在代码中执行此操作不更可取。如果你有20个按钮(正如你在问题评论中提到的那样),你应该在XAML中创建它们。
如果你真的想在代码中严格处理它们,你应该设置一个MVVM-style应用程序。这些类型的模型可以非常强大,但最初要学习起来很复杂。