Access the value of button and checkbox of an XAML in other another class in a wpf c# application
Asked Answered
L

1

1

I'm working on a WPF Kinect project. It's one of the developer toolkit samples of Windows Kinect and it's called "Kinect Explorer". You can download it from the Kinect Developer Toolkit SDK ver 1.5. In kinectwindow.xaml I added a button and a checkbox. Also, there is a class called kinectskeleton.cs in which I created two DataTables and a boolean variables. The first DataTable is filled in the OnRender function while the other is empty. The boolean variable is set by default to false. So, what I want is when the button in the kinectwindow.xaml.cs is pressed the latest data in the filled DataTable is copied to the empty one. Then, when the checkbox is checked, the boolean value is set to true. So, how to do this?

I defined a function in the class kinectskeleton.cs that copies the data from the filled to the empty DataTable. In the OnClick function of the button of kinectwindow.xaml.cs, I created an object from class kinectskeleton and called this function but both DataTables are empty. Same for the checkbox in the CheckBox_Checked function: I set the boolean value of the class kinectskelton to true (and in the unchecked function I set it to false). But, the result is that in the kinectskelton class it's always set to the default value (false) and never enters the if condition I made for it to enter when it's true.

Hope it's now more clear and waiting for any suggestions. To download the toolkit, here is the link: http://www.microsoft.com/en-us/kinectforwindows/develop/developer-downloads.aspx

part of my code:

//------------------------------------------------------------------------------
// <copyright file="KinectWindow.xaml.cs" company="Microsoft">
//     Copyright (c) Microsoft Corporation.  All rights reserved.
// </copyright>
//------------------------------------------------------------------------------

namespace Microsoft.Samples.Kinect.KinectExplorer
{
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Input;
    using Microsoft.Kinect;
    using Microsoft.Samples.Kinect.WpfViewers;

    /// <summary>
    /// Interaction logic for KinectWindow.xaml.
    /// </summary>
    public partial class KinectWindow : Window
    {
        public static readonly DependencyProperty KinectSensorProperty =
            DependencyProperty.Register(
                "KinectSensor",
                typeof(KinectSensor),
                typeof(KinectWindow),
                new PropertyMetadata(null));

        private readonly KinectWindowViewModel viewModel;
        /// <summary>
        /// Initializes a new instance of the KinectWindow class, which provides access to many KinectSensor settings
        /// and output visualization.
        /// </summary>
        public KinectWindow()
        {
            this.viewModel = new KinectWindowViewModel();

            // The KinectSensorManager class is a wrapper for a KinectSensor that adds
            // state logic and property change/binding/etc support, and is the data model
            // for KinectDiagnosticViewer.
            this.viewModel.KinectSensorManager = new KinectSensorManager();

            Binding sensorBinding = new Binding("KinectSensor");
            sensorBinding.Source = this;
            BindingOperations.SetBinding(this.viewModel.KinectSensorManager, KinectSensorManager.KinectSensorProperty, sensorBinding);

            // Attempt to turn on Skeleton Tracking for each Kinect Sensor
            this.viewModel.KinectSensorManager.SkeletonStreamEnabled = true;

            this.DataContext = this.viewModel;

            InitializeComponent();
        }

        public KinectSensor KinectSensor
        {
            get { return (KinectSensor)GetValue(KinectSensorProperty); }
            set { SetValue(KinectSensorProperty, value); }
        }

        public void StatusChanged(KinectStatus status)
        {
            this.viewModel.KinectSensorManager.KinectSensorStatus = status;
        }

        private void Swap_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Grid colorFrom = null;
            Grid depthFrom = null;

            if (this.MainViewerHost.Children.Contains(this.ColorVis))
            {
                colorFrom = this.MainViewerHost;
                depthFrom = this.SideViewerHost;
            }
            else
            {
                colorFrom = this.SideViewerHost;
                depthFrom = this.MainViewerHost;
            }

            colorFrom.Children.Remove(this.ColorVis);
            depthFrom.Children.Remove(this.DepthVis);
            colorFrom.Children.Insert(0, this.DepthVis);
            depthFrom.Children.Insert(0, this.ColorVis);
        }
        public KinectSkeleton ks = new KinectSkeleton();
        private void Calibrate_Click(object sender, RoutedEventArgs e)
        {

            ks.setcurrentdt();

        }

        private void AngleDifference_Checked(object sender, RoutedEventArgs e)
        {

            ks.is_checked = true;
        }

        private void AngleDifference_Unchecked(object sender, RoutedEventArgs e)
        {
            ks.is_checked = false;
        }


            }
}

    /// <summary>
    /// A ViewModel for a KinectWindow.
    /// </summary>
    public class KinectWindowViewModel : DependencyObject
    {
        public static readonly DependencyProperty KinectSensorManagerProperty =
            DependencyProperty.Register(
                "KinectSensorManager",
                typeof(KinectSensorManager),
                typeof(KinectWindowViewModel),
                new PropertyMetadata(null));

        public KinectSensorManager KinectSensorManager
        {
            get { return (KinectSensorManager)GetValue(KinectSensorManagerProperty); }
            set { SetValue(KinectSensorManagerProperty, value); }
        }
    }


}

namespace Microsoft.Samples.Kinect.WpfViewers
{
    using System.Collections.Generic;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Media;
    using Microsoft.Kinect;
    using System.Data;
    using System.Windows.Media.Media3D;
    using System.Globalization;

    /// <summary>
    /// This control is used to render a player's skeleton.
    /// If the ClipToBounds is set to "false", it will be allowed to overdraw
    /// it's bounds.
    /// </summary>
    public class KinectSkeleton : Control
    {
        public bool is_checked=false;
        public DataTable x = new DataTable();
        public DataTable y = new DataTable();
protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);

            var currentSkeleton = this.Skeleton;

            // Don't render if we don't have a skeleton, or it isn't tracked
            if (drawingContext == null || currentSkeleton == null || currentSkeleton.TrackingState == SkeletonTrackingState.NotTracked)
            {
                return;
            }

            // Displays a gradient near the edge of the display where the skeleton is leaving the screen
            this.RenderClippedEdges(drawingContext);

            switch (currentSkeleton.TrackingState)
            {
                case SkeletonTrackingState.PositionOnly:
                    if (this.ShowCenter)
                    {
                        drawingContext.DrawEllipse(
                            this.centerPointBrush,
                            null,
                            this.Center,
                            BodyCenterThickness * this.ScaleFactor,
                            BodyCenterThickness * this.ScaleFactor);
                    }

                    break;
                case SkeletonTrackingState.Tracked:


                   // here i defined the DataTables



                        if (is_checked == false)
                        {
                            //fill data table x with value a
                        }
                        else
                        {
                            //fill data table x with value b
                        }

                    break;
            }
        }

 public void setcurrentdt()
        {

            //fill empty datatable "y" with filled one "x"
              y = x.Copy();
        }
    }
}

xaml code of the checkbox:

   <Window x:Class="Microsoft.Samples.Kinect.KinectExplorer.KinectWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:Microsoft.Samples.Kinect.KinectExplorer"
        xmlns:kt="clr-namespace:Microsoft.Samples.Kinect.WpfViewers;assembly=Microsoft.Samples.Kinect.WpfViewers"
        Title="Kinect Explorer" Width="839" Height="768">
    <Window.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="pack://application:,,,/Microsoft.Samples.Kinect.WpfViewers;component/KinectControlResources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
            <local:KinectWindowsViewerSwapCommand x:Key="SwapCommand"/>
        </ResourceDictionary>
    </Window.Resources>
    <Window.CommandBindings>
        <CommandBinding Command="{StaticResource SwapCommand}" Executed="Swap_Executed"/>
    </Window.CommandBindings>
    <Window.InputBindings>
        <KeyBinding Key="Back"  Command="{StaticResource SwapCommand}"/>
    </Window.InputBindings>

    <Grid Name="layoutGrid" Margin="10 0 10 0" TextBlock.FontFamily="{StaticResource KinectFont}">        
        <Grid.RowDefinitions>
            <!-- The title bar -->
            <RowDefinition Height="Auto"/>
            <!-- The main viewer -->
            <RowDefinition Height="*" MinHeight="300"/>
            <!-- The audio panel -->
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <!-- The main viewer -->
            <ColumnDefinition Width="*" MinWidth="400"/>
            <!-- The side panels -->
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <DockPanel Grid.Row="0" Grid.ColumnSpan="2" Margin="10 0 10 20">
            <Image DockPanel.Dock="Left" Source="Images\Logo.png" Stretch="None" HorizontalAlignment="Left" Margin="0 10 0 0"/>
            <TextBlock DockPanel.Dock="Right" 
                       HorizontalAlignment="Right" 
                       VerticalAlignment="Bottom" 
                       Foreground="{StaticResource TitleForegroundBrush}" FontSize="{StaticResource LabelFontSize}">Kinect Explorer</TextBlock>
            <Image Source="Images\Status.png" Stretch="None" HorizontalAlignment="Center"/>
        </DockPanel>

        <!-- The main viewer -->
        <Grid Grid.Column="0" Grid.Row="1" Margin="10" >
            <Grid Name="MainViewerHost">
                <Grid Name="ColorVis" Background="{StaticResource DarkNeutralBrush}">
                    <Viewbox HorizontalAlignment="Center" VerticalAlignment="Center" Stretch="Uniform">
                        <!-- Make the colorViewer and skeletonViewer overlap entirely. -->
                        <Grid>
                            <kt:KinectColorViewer x:Name="ColorViewer" KinectSensorManager="{Binding KinectSensorManager}" CollectFrameRate="True" RetainImageOnSensorChange="True" />
                            <Canvas>
                                <kt:KinectSkeletonViewer 
                                    KinectSensorManager="{Binding KinectSensorManager}"
                                    Visibility="{Binding KinectSensorManager.ColorStreamEnabled, Converter={StaticResource BoolToVisibilityConverter}}"
                                    Width="{Binding ElementName=ColorViewer,Path=ActualWidth}"
                                    Height="{Binding ElementName=ColorViewer,Path=ActualHeight}"
                                    ImageType="Color" />
                            </Canvas>
                        </Grid>
                    </Viewbox>
                    <Border 
                        TextBlock.Foreground="{StaticResource LabelForegroundBrush}" 
                        HorizontalAlignment="Right" VerticalAlignment="Top" 
                        Background="{StaticResource MediumNeutralBrush}"
                        Width="50" Height="50">
                        <StackPanel Orientation="Vertical" >
                            <TextBlock FontSize="{StaticResource HeaderFontSize}" Text="{Binding ElementName=ColorViewer, Path=FrameRate}" HorizontalAlignment="Center" Margin="-2"/>
                            <TextBlock FontSize="{StaticResource FPSFontSize}" HorizontalAlignment="Center" Margin="-2">FPS</TextBlock>
                        </StackPanel>
                    </Border>                   
                    <Rectangle Fill="#7777" Visibility="{Binding KinectSensorManager.ColorStreamEnabled, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}"/>
                </Grid>
            </Grid>
        </Grid>

        <!-- The Audio panel -->
        <Grid Grid.Row="2" Grid.Column="0"
              Margin="10 10 10 20"
              VerticalAlignment="Top">
            <kt:KinectAudioViewer 
                x:Name="kinectAudioViewer" 
                HorizontalAlignment="Stretch" 
                VerticalAlignment="Stretch"                 
                KinectSensorManager="{Binding KinectSensorManager}"/>
        </Grid>

        <!-- The side panels-->
        <StackPanel 
            Orientation="Vertical" 
            Grid.Column="1" 
            Grid.Row="1" 
            Grid.RowSpan="2" 
            Margin="10"
            HorizontalAlignment="Left" VerticalAlignment="Top">
            <Grid Name="SideViewerHost" Width="200" Height="150">
                <Grid Name="DepthVis" Background="{StaticResource DarkNeutralBrush}">
                    <Viewbox Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center">
                        <!-- Make the depthViewer and skeletonViewer overlap entirely. -->
                        <Grid>
                            <kt:KinectDepthViewer 
                            x:Name="DepthViewer"
                            KinectSensorManager="{Binding KinectSensorManager}"
                            CollectFrameRate="True" 
                            RetainImageOnSensorChange="True"/>
                            <Canvas>
                                <kt:KinectSkeletonViewer 
                                KinectSensorManager="{Binding KinectSensorManager}"
                                Visibility="{Binding KinectSensorManager.DepthStreamEnabled, Converter={StaticResource BoolToVisibilityConverter}}"
                                Width="{Binding ElementName=DepthViewer, Path=ActualWidth}"
                                Height="{Binding ElementName=DepthViewer, Path=ActualHeight}"
                                ShowBones="true" ShowJoints="true" ShowCenter="true" ImageType="Depth" />
                            </Canvas>
                        </Grid>
                    </Viewbox>
                    <Border 
                        TextBlock.Foreground="{StaticResource LabelForegroundBrush}" 
                        HorizontalAlignment="Right" VerticalAlignment="Top" 
                        Background="{StaticResource MediumNeutralBrush}"
                        Width="50" Height="50">
                        <StackPanel Orientation="Vertical" >                            
                            <TextBlock FontSize="{StaticResource HeaderFontSize}" Text="{Binding ElementName=DepthViewer, Path=FrameRate}" HorizontalAlignment="Center" Margin="-2"/>
                            <TextBlock FontSize="{StaticResource FPSFontSize}" HorizontalAlignment="Center" Margin="-2">FPS</TextBlock>
                        </StackPanel>
                    </Border>
                    <Rectangle Fill="#7777" Visibility="{Binding KinectSensorManager.DepthStreamEnabled, Converter={StaticResource BoolToVisibilityConverter}, ConverterParameter=True}"/>
                </Grid>
                <Button HorizontalAlignment="Left" VerticalAlignment="Top" Command="{StaticResource SwapCommand}">
                    <Button.Template>
                        <ControlTemplate>
                            <Border Width="50" Height="50">
                                <Border.Style>
                                    <Style>
                                        <Style.Setters>
                                            <Setter Property="Border.Background" Value="{StaticResource MediumNeutralBrush}"/>
                                        </Style.Setters>
                                        <Style.Triggers>
                                            <DataTrigger Binding="{Binding RelativeSource={x:Static RelativeSource.TemplatedParent}, Path=IsMouseOver}" Value="True">
                                                <Setter Property="Border.Background" Value="{StaticResource DarkNeutralBrush}"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Border.Style>
                                <Image Source="Images/swap.png"/>
                            </Border>
                        </ControlTemplate>
                    </Button.Template>
                </Button>                
            </Grid>

            <kt:KinectSettings KinectSensorManager="{Binding KinectSensorManager}" Margin="0 20 0 0" />

        </StackPanel>
        <Button Content="Calibrate"  Height="23" x:Name="Calibrate" x:FieldModifier="public" Width="75" Margin="213,45,289,435" Grid.RowSpan="2" Click="Calibrate_Click" />
        <CheckBox Content="AngleDifference"  Height="25" x:Name="AngleDifference" x:FieldModifier="public" Width="135" Margin="0,45,137,433" Grid.RowSpan="2" Checked="AngleDifference_Checked" HorizontalAlignment="Right" Unchecked="AngleDifference_Unchecked" />
    </Grid> 
</Window>

ViewModel class:

public class ViewModel
    {

        public bool IsChecked { get; set; }
        public bool is_clicked { get; set; }

    }
Liquesce answered 13/7, 2012 at 1:4 Comment(1)
Until we can see the code, there's not much that we can offer in the way of suggestions. Try to keep the code samples limited to where you think the problem is - no need to post your entire project.Gown
D
2

Without seeing the complete KinectWindow.xaml file or downloading the SDK I'm taking a bit of a guess, but it seems to me that your problems are caused by having two different instances of KinectSkeleton:

  • ks that you're instantiating in KinectWindow, setting its is_checked property and calling setcurrentdt
  • the one declared somewhere in KinectWindow.xaml in which OnRender is being called.

How to fix this problem?

  • Find KinectSkeleton in KinectWindow.xaml. It should be defined like this (instead of local, a different namespace prefix could be used):
<local:KinectSkeleton ... />
  • Give it a name so that you can reference it from code behind in KinextWindow.xaml.cs by adding the x:Name attribute. If you name it ks you won't need to change your existing code modifications:
<local:KinectSkeleton x:Name="ks" ... />
  • Delete your declaration of KinectSkeleton class in code behind to prevent the clash:
public KinectSkeleton ks = new KinectSkeleton();

Now you will have only a single instance of KinectSkeleton, therefore OnRender will work with the same data that you're modifying from your event handlers.

Decoteau answered 14/7, 2012 at 13:29 Comment(4)
I'm sure the KinectWindow.xaml uses KinectSkeleton, there is two KinectSkeletonViewer & no KinectSkeleton,I've updated the post with the KinectWindow.xaml,I think also if I can access the is_checked of the checkbox and is_clicked of the button will be easier right?I did what you told me in the last question but when putting"DataContext = new ViewModel();" after InitializeComponent() the project stopped working,so 2 ways 1-to access the current kinectskeleton from the KinectWindow.xaml 2-is to access the is_clicked and is_checked from the KinectSkeleton.cs so can you tell me how please?Liquesce
@user1460166 I suppose KinectSkeleton is used inside KinectSkeletonViewer. You should check its cs and and/or xaml file. Or search where in the solution KinectSkeleton is used by pressing Shift+F12 in VisualStudio. The app stopped working after you set your own DataContext because it already follows the MVVM pattern and has a DataContext set (this.DataContext = this.viewModel; in KinectWindows constructor). If you want to use binding, add you properties to KinectWindowViewModel, but your approach should work as well once you interact with the right instance of KinectSkeleton.Decoteau
if I want to go for the binding solution in which retrieve the is_checked of the checkbox and when_clicked of the button, then can you please apply what needed to be done on my above code? in the xaml, and cs classes? many thanks and sorry for disturbing youLiquesce
@user1460166 Did you manage to get it working with the current approach? Changing the approach will not make your problems go away. If you're still having problems, try following my previous instructions. Ask if you have any difficulties with it and I'll try to help you.Decoteau

© 2022 - 2024 — McMap. All rights reserved.