2009-05-15 4 views
59

S'il est trivial de stocker l'état coché d'une case dans une variable à l'aide de l'événement Click de la case, comment le ferais-je via la liaison de données? Tous les exemples que j'ai trouvés ont mis à jour l'interface utilisateur à partir d'une source de données, ou lier un contrôle à un autre; Je veux mettre à jour une variable membre lorsque la case est cochée.WPF checkbox binding

TIA pour tous les pointeurs ...

Répondre

40

Vous avez besoin d'une propriété de dépendance pour cela:

public BindingList<User> Users 
    { 
     get { return (BindingList<User>)GetValue(UsersProperty); } 
     set { SetValue(UsersProperty, value); } 
    } 

public static readonly DependencyProperty UsersProperty = 
    DependencyProperty.Register("Users", typeof(BindingList<User>), 
     typeof(OptionsDialog)); 

Une fois cela fait, vous lier la case à la propriété de dépendance:

<CheckBox x:Name="myCheckBox" IsChecked="{Binding ElementName=window1, 
    Path=CheckBoxIsChecked}" /> 

Pour cela fonctionne, vous devez nommer votre fenêtre ou UserControl dans sa balise ouvrante, et utiliser ce nom dans le ElementName paramètre.

Avec ce code, lorsque vous modifiez la propriété du côté du code, vous modifiez la zone de texte. De plus, chaque fois que vous cochez/décochez la case, la propriété de dépendance changera aussi.

EDIT:

Un moyen facile de créer une propriété de dépendance est de taper un propdp d'extrait, qui vous donnera le code général des propriétés de dépendance.

Tout le code:

XAML:

<Window x:Class="StackOverflowTests.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Window1" x:Name="window1" Height="300" Width="300"> 
    <Grid> 
    <StackPanel Orientation="Vertical"> 
     <CheckBox Margin="10" x:Name="myCheckBox" 
       IsChecked="{Binding ElementName=window1, Path=IsCheckBoxChecked}" 
       >Bound CheckBox</CheckBox> 
     <Label Content="{Binding ElementName=window1, Path=IsCheckBoxChecked}" 
       ContentStringFormat="Is checkbox checked? {0}"></Label> 
     </StackPanel>  
    </Grid> 
</Window> 

C#:

using System.Windows; 

namespace StackOverflowTests 
{ 
    /// <summary> 
    /// Interaction logic for Window1.xaml 
    /// </summary> 
    public partial class Window1 : Window 
    { 
     public bool IsCheckBoxChecked 
     { 
      get { return (bool)GetValue(IsCheckBoxCheckedProperty); } 
      set { SetValue(IsCheckBoxCheckedProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for 
     //IsCheckBoxChecked. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty IsCheckBoxCheckedProperty = 
      DependencyProperty.Register("IsCheckBoxChecked", typeof(bool), 
      typeof(Window1), new UIPropertyMetadata(false)); 

     public Window1() 
     {    
      InitializeComponent(); 
     } 
    } 
} 

Remarquez comment le seul code est derrière la propriété de dépendance. L'étiquette et la case à cocher y sont liées. Si la case à cocher change, l'étiquette change également.

+0

Merci pour la réponse. Il semble que "ElementName" soit l'ingrédient clé manquant. – Number8

+0

Heureux que je pourrais aider =) – Carlo

+2

Cela fonctionnera, mais il n'est pas vrai que "vous avez besoin d'une propriété de dépendance pour cela." Voir les solutions ci-dessous ... tout ce dont vous avez besoin est une propriété sur votre viewmodel à lier. –

4

si vous avez la propriété « MyProperty » sur vos données de classe, alors vous lier le IsChecked comme ça .... (le convertisseur est facultatif, mais parfois vous avez besoin que)

<Window.Resources> 
<local:MyBoolConverter x:Key="MyBoolConverterKey"/> 
</Window.Resources> 
<checkbox IsChecked="{Binding Path=MyProperty, Converter={StaticResource MyBoolConverterKey}}"/> 
+6

Si votre propriété est déjà booléen, pas de convertisseur est nécessaire. –

+0

yup, c'est pourquoi son "optionnel" :-) –

+0
60

Vous devez rendre votre bidirectionnel de liaison:

<checkbox IsChecked="{Binding Path=MyProperty, Mode=TwoWay}"/> 
+0

Merci Thomas, qui l'a trié pour moi, j'utilisais la propriété Content. – Spidey

1

Cela devrait être plus facile que cela.Il suffit d'utiliser:

<Checkbox IsChecked="{Binding Path=myVar, UpdateSourceTrigger=PropertyChanged}" /> 
8

Bonjour ceci est ma première fois détachement en s'il vous plaît soyez patient: ma réponse était de créer une propriété simple:

 public bool Checked 
     { get; set; } 

ensuite pour définir le contexte de données de la Checkbox (appelé CB1):

cb1.DataContext = this; 

ensuite de lier la proerty IsChecked de celui-ci dans le XAML

IsChecked="{Binding Checked}" 

Le code est comme ceci:

// the xaml 
 

 
<CheckBox x:Name="cb1" HorizontalAlignment="Left" 
 
     Margin="439,81,0,0" VerticalAlignment="Top" 
 
     Height="35" Width="96" IsChecked="{Binding Checked}"/> 
 
    
// the c# 
 

 
public partial class MainWindow : Window 
 
    { 
 
     public bool Checked 
 
     { get; set; } 
 
    
 

 
     public MainWindow() 
 
     { 
 
      InitializeComponent(); 
 

 
      cb1.DataContext = this; 
 
     } 
 

 
     private void myyButton_Click(object sender, RoutedEventArgs e) 
 
     { 
 

 
      MessageBox.Show(Checked.ToString()); 
 

 

 
     } 
 
    }

1

Cela fonctionne pour moi (code essentiel que inclus, remplir plus pour vos besoins):

En XAML un contrôle utilisateur est défini:

<UserControl x:Class="Mockup.TestTab" ......> 
    <!-- a checkbox somewhere within the control --> 
    <!-- IsChecked is bound to Property C1 of the DataContext --> 
    <CheckBox Content="CheckBox 1" IsChecked="{Binding C1, Mode=TwoWay}" /> 
</UserControl> 

Code derrière pour UserControl

public partial class TestTab : UserControl 
{ 
    public TestTab() 
    { 
     InitializeComponent(); // the standard bit 

    // then we set the DataContex of TestTab Control to a MyViewModel object 
    // this MyViewModel object becomes the DataContext for all controls 
     // within TestTab ... including our CheckBox 
     DataContext = new MyViewModel(....); 
    } 

} 

Quelque part dans la classe solution MyViewModel est définie

public class MyViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 
    private bool m_c1 = true; 

    public bool C1 { 
     get { return m_c1; } 
     set { 
      if (m_c1 != value) { 
       m_c1 = value; 
       if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs("C1")); 
      } 
     } 
    } 
}