WPF Checkbox Bindung

76

Während es trivial ist, den aktivierten Status eines Kontrollkästchens mithilfe des Click-Ereignisses des Kontrollkästchens in einer Variablen zu speichern, wie würde ich dies über die Datenbindung tun? Bei allen Beispielen, die ich gefunden habe, wurde die Benutzeroberfläche von einer Datenquelle aktualisiert oder ein Steuerelement an ein anderes gebunden. Ich möchte eine Mitgliedsvariable aktualisieren, wenn das Kontrollkästchen aktiviert ist.

TIA für alle Hinweise ...

Nummer 8
quelle

Antworten:

54

Dazu benötigen Sie eine Abhängigkeitseigenschaft:

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

Sobald dies erledigt ist, binden Sie das Kontrollkästchen an die Abhängigkeitseigenschaft:

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

Damit dies funktioniert, müssen Sie Ihr Fenster oder UserControl in seinem Öffnungs-Tag benennen und diesen Namen im Parameter ElementName verwenden.

Mit diesem Code ändern Sie jedes Mal, wenn Sie die Eigenschaft auf der Codeseite ändern, das Textfeld. Wenn Sie das Textfeld aktivieren / deaktivieren, ändert sich auch die Abhängigkeitseigenschaft.

BEARBEITEN:

Eine einfache Möglichkeit, eine Abhängigkeitseigenschaft zu erstellen, besteht darin, das Snippet propdp einzugeben, mit dem Sie den allgemeinen Code für die Abhängigkeitseigenschaften erhalten.

Der ganze 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}" />
        </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();
        }
    }
}

Beachten Sie, dass der einzige Code dahinter die Abhängigkeitseigenschaft ist. Sowohl das Etikett als auch das Kontrollkästchen sind daran gebunden. Wenn sich das Kontrollkästchen ändert, ändert sich auch die Beschriftung.

Carlo
quelle
1
Danke für die Antwort. Es scheint, dass "ElementName" die fehlende Schlüsselzutat war.
Nummer 8
5
Dies wird funktionieren, aber es ist nicht wahr, dass "Sie dafür eine Abhängigkeitseigenschaft benötigen". Siehe Lösungen unten ... alles, was Sie brauchen, ist eine Eigenschaft in Ihrem Ansichtsmodell, an die Sie sich binden können.
Randy Gamage
81

Sie müssen Ihre Bindung bidirektional machen:

<checkbox IsChecked="{Binding Path=MyProperty, Mode=TwoWay}"/>
Thomas Levesque
quelle
Danke Thomas, das hat es für mich sortiert, ich habe die Content-Eigenschaft verwendet.
Spidey
13

Hallo, dies ist mein erstes Posting. Bitte haben Sie etwas Geduld: Meine Antwort war, eine einfache Eigenschaft zu erstellen:

public bool Checked { get; set; }

So stellen Sie den Datenkontext des Kontrollkästchens (cb1 genannt) ein:

cb1.DataContext = this;

Dann binden Sie die IsChecked-Eigenschaft davon in die xaml

IsChecked="{Binding Checked}"

Der Code lautet wie folgt:

XAML

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

Code dahinter

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());
    }
}
Abraham Camhy
quelle
4

Wenn Sie die Eigenschaft "MyProperty" für Ihre Datenklasse haben, binden Sie das IsChecked wie folgt ... (der Konverter ist optional, aber manchmal benötigen Sie das)

<Window.Resources>
<local:MyBoolConverter x:Key="MyBoolConverterKey"/>
</Window.Resources>
<checkbox IsChecked="{Binding Path=MyProperty, Converter={StaticResource MyBoolConverterKey}}"/>
Muad'Dib
quelle
yup, deshalb ist es "optional" :-)
Muad'Dib
<checkbox IsChecked = "{Binding Path = Checked, Mode = TwoWay}" public bool Checked {get {return _isChecked;} set {_isChecked = value;}} Keine Freude; _isChecked wird nie geändert.
Nummer 8
Überprüfen Sie dann Ihren DataContext, ich benutze diesen selbst und er funktioniert wie ein Zauber.
Muad'Dib
2

Sollte einfacher sein. Benutz einfach:

<Checkbox IsChecked="{Binding Path=myVar, UpdateSourceTrigger=PropertyChanged}" />
Tim W.
quelle
1

Dies funktioniert für mich (nur wesentlicher Code enthalten, mehr für Ihre Bedürfnisse ausfüllen):

In XAML ist ein Benutzersteuerelement definiert:

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

Im Code dahinter für 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(....);
    }

}

Irgendwo in der Lösungsklasse ist MyViewModel definiert

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"));
            }
        }
    }
}
pjm
quelle