How to make a control in XAML public in order to be seen in other classes

Tak picture Tak · Jul 11, 2012 · Viewed 33.1k times · Source

I'm working in wpf application i made a checkbox in the XAML, then my code calls a function in a class and in this function there is an if condition where its checking on whether the checkbox is checked or not but the checkbox is not seen in this class, so how to do this?

Many thanks

EDIT:

Here is the steps I did: i created the ViewModel class under the same project of KinectSkeleton as shown: ViewModel class:

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

and in the KinectSkeleton I defined a property as shown:

public static readonly DependencyProperty ViewModelProperty =
           DependencyProperty.Register("ViewModelH", typeof(ViewModel), typeof(KinectSkeleton), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));


public ViewModel ViewModelH
{
    get
    {
        return (ViewModel)GetValue(ViewModelProperty);
    }
    set
    {
        SetValue(ViewModelProperty, value);
    }
}

and the code of the checkbox and button in the KinectWindow.xaml is :

<Button Content="Calibrate" Height="24" x:Name="Calibrate" x:FieldModifier="public" Width="90" Click="Calibrate_Click" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Left" DockPanel.Dock="Left" Panel.ZIndex="0" Padding="0" VerticalAlignment="Center" />
<CheckBox IsChecked="{Binding Mode=TwoWay, Path=IsChecked}" Content="AngleDifference" Height="22" x:Name="AngleDifference" x:FieldModifier="public" Width="117" Checked="AngleDifference_Checked" Unchecked="AngleDifference_Unchecked" HorizontalAlignment="Left" VerticalAlignment="Center" Panel.ZIndex="1" HorizontalContentAlignment="Left" />

and in the KinectSkeleton where i want to check the value of the checkbox i write:

    if (this.ViewModelH.IsChecked == false)
    // if(f.is_chekced==false)
    {
        // do something
    }

now i want to know what to write in the is_checked event of the checkbox and is_clicked of the button? also is there anything missing in my above steps as i feel that till now the kinect skeleton property is not binded to the checkbox is_checked value?

Answer

Damir Arh picture Damir Arh · Jul 11, 2012

Using the following XML you can define a control as a public field on the class to be able to access it from other classes:

<CheckBox x:Name="myCheckBox" x:FieldModifier="public" />

Now you can access the field directly in code:

if (win.myCheckBox.IsChecked.Value)
{
    // ...
}

I agree with H.B., though, that using the MVVM pattern is a better way to do it. Other parts of your code shouldn't be aware of your UI or directly access it.

EDIT:

With the MVVM approach you should first define your view model class:

public class ViewModel
{
    public bool IsChecked { get; set; }
}

Then you set an instance of this class as DataContext:

  • either in code, e.g. window constructor:
public MyWindow()
{
    InitializeComponent();
    DataContext = new ViewModel();
}
  • or in XAML, e.g. App.xaml:
<Application x:Class="WpfApplication2.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:vm="clr-namespace:WpfApplication2"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <vm:ViewModel x:Key="ViewModel" />
    </Application.Resources>
</Application>

Now you can bind your CheckBox to a property in ViewModel:

<CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" />

All that's left is to pass the ViewModel instance to your OnRender function. It is stored in the DataContext property of your window.

EDIT 2:

BTW: You really should have asked that before you accepted the answer.

I'm not sure what you are trying to attempt with the is_clicked property. To set this flag when the button is clicked, you need a Command:

public class CalibrateCommand : ICommand
{
    private ViewModel viewModel;

    public CalibrateCommand(ViewModel viewModel)
    {
        this.viewModel = viewModel;
    }

    public void Execute(object parameter)
    {
        viewModel.IsClicked = true;
    }

    public bool CanExecute()
    {
        return true;
    }
}

You add an instance of this command to your view model:

public class ViewModel
{
    public bool IsChecked { get; set; }
    public bool IsClicked { get; set; }
    public ICommand CalibrateCommand { get; set; }

    public ViewModel()
    {
        CalibrateCommand = new CalibrateCommand(this);
    }
}

You bind it to the button like this:

<Button Content="Calibrate" Height="24" x:Name="Calibrate" x:FieldModifier="public" Width="90" Click="Calibrate_Click" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Left" DockPanel.Dock="Left" Panel.ZIndex="0" Padding="0" VerticalAlignment="Center" Command="{Binding CalibrateCommand}" />

You don't need to handle any events of the CheckBox and the Button, everything is handled by the binding.

If you added a dependency property to KinectSkeleton you should bind it to the view model:

<kt:KinectSkeleton ViewModelH="{Binding}" />