Enlace de casilla de verificación de WPF

77

Si bien es trivial almacenar el estado marcado de una casilla de verificación en una variable utilizando el evento Click de la casilla de verificación, ¿cómo lo haría mediante el enlace de datos? Todos los ejemplos que he encontrado tienen la interfaz de usuario actualizada desde alguna fuente de datos o vinculan un control a otro; Quiero actualizar una variable miembro cuando se hace clic en la casilla de verificación.

TIA para cualquier puntero ...

Numero 8
fuente

Respuestas:

53

Necesita una propiedad de dependencia para esto:

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

Una vez hecho esto, vincula la casilla de verificación a la propiedad de dependencia:

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

Para que eso funcione, debe nombrar su Ventana o UserControl en su etiqueta de apertura, y usar ese nombre en el parámetro ElementName.

Con este código, siempre que cambie la propiedad en el lado del código, cambiará el cuadro de texto. Además, siempre que marque / desmarque el cuadro de texto, la propiedad de dependencia también cambiará.

EDITAR:

Una forma sencilla de crear una propiedad de dependencia es escribir el fragmento propdp, que le proporcionará el código general de las propiedades de dependencia.

Todo el codigo:

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

Observe cómo el único código subyacente es la propiedad de dependencia. Tanto la etiqueta como la casilla de verificación están vinculadas a ella. Si la casilla de verificación cambia, la etiqueta también cambia.

Carlo
fuente
1
Gracias por la respuesta. Parece que "ElementName" era el ingrediente clave que faltaba.
Number8
6
Esto funcionará, pero no es cierto que "necesite una propiedad de dependencia para esto". Vea las soluciones a continuación ... todo lo que necesita es una propiedad en su modelo de vista para vincularse.
Randy Gamage
83

Debes hacer tu encuadernación bidireccional:

<checkbox IsChecked="{Binding Path=MyProperty, Mode=TwoWay}"/>
Thomas Levesque
fuente
Gracias Thomas, eso me solucionó, estaba usando la propiedad Contenido.
Spidey
13

Hola, esta es la primera vez que publico, así que tenga paciencia: mi respuesta fue crear una propiedad simple:

public bool Checked { get; set; }

Luego, para configurar el contexto de datos de la casilla de verificación (llamado cb1):

cb1.DataContext = this;

Luego, para vincular la propiedad IsChecked de la misma en el xaml

IsChecked="{Binding Checked}"

El código es así:

XAML

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

Código detrás

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

si tiene la propiedad "MyProperty" en su clase de datos, entonces enlaza el IsChecked así ... (el convertidor es opcional, pero a veces lo necesita)

<Window.Resources>
<local:MyBoolConverter x:Key="MyBoolConverterKey"/>
</Window.Resources>
<checkbox IsChecked="{Binding Path=MyProperty, Converter={StaticResource MyBoolConverterKey}}"/>
Muad'Dib
fuente
sí, por eso es "opcional" :-)
Muad'Dib
<checkbox IsChecked = "{Binding Path = Checked, Mode = TwoWay}" public bool Checked {get {return _isChecked;} set {_isChecked = value;}} Sin alegría; _isChecked nunca se cambia.
Number8
verifique su DataContext entonces, lo estoy usando yo mismo y funciona como un encanto.
Muad'Dib
2

Debería ser más fácil que eso. Solo usa:

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

Esto funciona para mí (solo se incluye el código esencial, complete más para sus necesidades):

En XAML se define un control de usuario:

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

En código subyacente para 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(....);
    }

}

En algún lugar de la clase de solución se define MyViewModel

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
fuente