web-dev-qa-db-fra.com

Comment rendre un contrôle en XAML public pour être vu dans d'autres classes

Je travaille dans l'application wpf j'ai fait une case à cocher dans le XAML, puis mon code appelle une fonction dans une classe et dans cette fonction il y a une condition if où sa vérification si la case est cochée ou non mais la case n'est pas vue dans cette classe, alors comment faire?

Merci beaucoup

ÉDITER:

Voici les étapes que j'ai faites: j'ai créé la classe ViewModel sous le même projet de KinectSkeleton comme indiqué: Classe ViewModel:

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

et dans KinectSkeleton j'ai défini une propriété comme indiqué:

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);
    }
}

et le code de la case à cocher et du bouton dans KinectWindow.xaml est:

<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" />

et dans le KinectSkeleton où je veux vérifier la valeur de la case à cocher que j'écris:

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

maintenant je veux savoir quoi écrire dans l'événement is_checked de la case à cocher et is_clicked du bouton? y a-t-il également quelque chose qui manque dans mes étapes ci-dessus car je pense que jusqu'à présent la propriété squelette kinect n'est pas liée à la valeur de la case à cocher is_checked?

27
Tak

En utilisant le code XML suivant, vous pouvez définir un contrôle en tant que champ public sur la classe pour pouvoir y accéder à partir d'autres classes:

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

Vous pouvez maintenant accéder directement au champ en code:

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

Je suis d'accord avec H.B., cependant, que l'utilisation du modèle MVVM est une meilleure façon de le faire. Les autres parties de votre code ne doivent pas être au courant de votre interface utilisateur ni y accéder directement.

ÉDITER:

Avec l'approche MVVM, vous devez d'abord définir votre classe de modèle de vue:

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

Ensuite, vous définissez une instance de cette classe comme DataContext:

  • soit en code, par ex. constructeur de fenêtre:
public MyWindow()
{
    InitializeComponent();
    DataContext = new ViewModel();
}
  • ou en XAML, par ex. 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>

Vous pouvez maintenant lier votre CheckBox à une propriété dans ViewModel:

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

Il ne vous reste plus qu'à passer l'instance ViewModel à votre fonction OnRender. Il est stocké dans la propriété DataContext de votre fenêtre.

EDIT 2:

BTW: Vous auriez vraiment dû demander cela avant d'accepter la réponse.

Je ne sais pas ce que vous essayez de faire avec le is_clicked propriété. Pour définir cet indicateur lorsque vous cliquez sur le bouton, vous avez besoin d'un 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;
    }
}

Vous ajoutez une instance de cette commande à votre modèle de vue:

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

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

Vous le liez au bouton comme ceci:

<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}" />

Vous n'avez pas besoin de gérer les événements de CheckBox et Button, tout est géré par la liaison.

Si vous avez ajouté une propriété de dépendance à KinectSkeleton, vous devez la lier au modèle de vue:

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

Ne rendez pas la case à cocher visible de l'extérieur, transmettez simplement l'état actuel de la case à cocher à la fonction ou à la classe. Considérez également binding la valeur de la case à cocher d'une classe dans le DataContext , l'accès direct aux contrôles peut être évité la plupart du temps dans WPF, voir aussi le - modèle MVVM .

7
H.B.