Como criar botões customizados para o Kinect for Windows – Fernando Henrique Ferreira
Fernando H. I. B. Ferreira 14/01/2014 15/01/2014 Kinect, Microsoft
Para ampliar as opções existentes é preciso criar controles customizados que herdem as características básicas de um botão. O Kinect for Windows Developer Toolkit contém uma classe chamada KinectButtonBase que funciona como base para criação de todo e qualquer botão que se comunica com o Kinect for Windows (por meio do WPF).
Observação: neste exemplo foi utilizada a versão 1.8 do Kinect for Windows Developer Toolkit, mas este exemplo é totalmente compatível com a versão 1.7 do mesmo developer toolkit.
Neste exemplo criaremos um botão com uma imagem de fundo. Este botão irá disparar dois eventos não nativos: um evento quando a mão passar por cima do controle (hand enter) e outro quando a mão deixar o controle (hand leave).
Para fazer o download desse exemplo utilize este link: Criando botões para o Kinect for Windows
Criando a classe do botão
Neste primeiro ponto será preciso criar a classe do botão customizado. Neste exemplo criarei um botão chamado "MyCustomKinectButton".
O código do botão é apresentado abaixo:
public class MyCustomKinectButton : KinectButtonBase {
public event EventHandler OnHandPointerEnter;
public event EventHandler OnHandPointerLeave;
public MyCustomKinectButton() {
private void InitializeControl() {
KinectRegion.AddHandPointerEnterHandler(this, OnHandPointerEnterHandler);
KinectRegion.AddHandPointerLeaveHandler(this, OnHandPointerLeaveHandler);
this.MouseEnter += OnMouseEnter;
this.MouseLeave += OnMouseLeave;
this.Style = (Style)Application.Current.FindResource(typeof(MyCustomKinectButton));
private void OnHandPointerLeaveHandler(object sender, HandPointerEventArgs e) {
ExecuteHandPointerLeave(this, e);
private void OnMouseLeave(object sender, System.Windows.Input.MouseEventArgs e) {
ExecuteHandPointerLeave(this, null);
private void OnHandPointerEnterHandler(object sender, HandPointerEventArgs e) {
ExecuteHandPointerEnter(this, e);
private void OnMouseEnter(object sender, System.Windows.Input.MouseEventArgs e) {
ExecuteHandPointerEnter(this, null);
private void ExecuteHandPointerEnter(object sender, HandPointerEventArgs e) {
if (this.OnHandPointerEnter != null) {
this.OnHandPointerEnter(this, e);
private void ExecuteHandPointerLeave(object sender, HandPointerEventArgs e) {
if (this.OnHandPointerLeave != null) {
this.OnHandPointerLeave(this, e);
ConfigImage();
private void ConfigImage() {
StackPanel mainPanel = this.GetTemplateChild("MainPanel") as StackPanel;
Image mainImage = this.GetTemplateChild("MainImage") as Image;
if (mainPanel != null && mainImage != null) {
SetImageSize(mainImage);
SetImage(mainImage);
private void SetImageSize(Image mainImage) {
if (this.ActualWidth > 0 && this.ActualHeight > 0) {
mainImage.Width = this.ActualWidth;
mainImage.Height = this.ActualHeight;
else if (this.Width > 0 && this.Height > 0) {
mainImage.Width = this.Width;
mainImage.Height = this.Height;
private static void SetImage(Image mainImage) {
Assembly currentAssembly = Assembly.GetAssembly(typeof(MyCustomKinectButton));
using (Stream s = currentAssembly.GetManifestResourceStream("WpfKinect.Images.visualstudio.png")) {
mainImage.Source = img;
– MyCustomKinectButton herda da classe KinectButtonBase.
– Existem dois eventos neste botão: OnHandPointerEnter e OnHandPointerLeave. Um deles é chamado quando a mão passa por cima do controle e o outro quando a mão deixa o controle. Veja que para a assinatura destes eventos temos de utilizar a classe KinectRegion (http://msdn.microsoft.com/en-us/library/microsoft.kinect.toolkit.controls.kinectregion_members.aspx). Além disso, associei estes mesmos dois eventos com os eventos MouseEnter e o MouseLeave existentes no controle. Desta forma o controle não perde o seu funcionamento quando usado com o mouse.
– O método OnApplyTemplate é sobrescrito: note que no construtor desta classe a propriedade Style é definida, carregando recursos associados com o tipo de dados MyCustomKinectButton. Além disso, no método OnApplyTemplate é definido o tamanho da imagem e a imagem que será carregada.
A imagem que será carregada e associada com o controle está embutida dentro do assembly do controle como um Embedded Resource – veremos como adicionar um Embedded Resource mais a frente – o código que faz acesso ao Embedded Resource pode ser encontrado no método SetImage.
Criando o dicionário de recursos
Um dicionário de recursos (resource dictionary) é um dicionário de objetos que podem ser utilizados via managed code e/ou via XAML. Geralmente, dicionários de recursos são utilizados na definição de templates para controles – e este será o seu uso neste exemplo.
Como padrão, crio um arquivo chamado Generic.xaml dentro de uma pasta chamada Themes, como na imagem abaixo:
O conteúdo do arquivo Generic.xaml pode ser encontrado logo abaixo:
xmlns:ck="clr-namespace:WpfKinect"
xmlns:local="clr-namespace:WpfKinect">
<Style TargetType="{x:Type local:MyCustomKinectButton}">
<ControlTemplate TargetType="local:MyCustomKinectButton">
<StackPanel x:Name="MainPanel">
<Image x:Name="MainImage" ClipToBounds="True">
<DropShadowEffect ShadowDepth="0" Color="Black" Opacity="1" BlurRadius="10"/>
Note que o arquivo se baseia no namespace do assembly corrente, e também perceba que o estilo (theme) descrito via XAML é orientado ao objeto que será renderizado, no caso o objeto MyCustomKinectButton.
Detalhe adicional no XAML: veja que existe uma trigger para a propriedade IsMouseOver. Essa trigger quando acionada inicia uma animação que inclui uma sombra ao redor da imagem.
Abaixo as imagens com o efeito de sombra (esquerda) e sem o defeito de sombra (direita).
Imagem incorporada ao assembly
Outro ponto importante a ser discutido é a origem da imagem. Neste exemplo fizemos uso de uma imagem incorporada ao assembly. Essa característica é vantajosa, pois torna a solução compacta e centralizada, sem exigir a existência de artefatos externos. Por outro lado, a incorporação de imagens, áudios e vídeos (como qualquer outro tipo de artefato) a um assembly pode ser negativa, pois pode tornar o tamanho do assembly maior.
Incorporar uma imagem a um assembly é simples, basta adicionar a imagem ao projeto (como na imagem abaixo), clicar com o botão direito sobre a imagem, acessar as propriedades da imagem e definir a propriedade "Build Action" como "Embedded Resource" (como em uma das imagens abaixo).
O código necessário para extração dos bytes da imagem do binário pode ser encontrado no método SetImage, e também é apresentado abaixo: