2009-05-15 31 views
59

Podczas gdy przechowywanie stanu zaznaczonego pola wyboru w zmiennej przy użyciu zdarzenia Click Click jest banalnie proste, w jaki sposób mogę to zrobić za pomocą wiązania danych? Wszystkie znalezione przykłady mają zaktualizowany interfejs użytkownika z jakiegoś źródła danych lub wiążą jedną kontrolę z drugą; Chcę zaktualizować zmienną składową po kliknięciu pola wyboru.Wiązanie pola wyboru WPF

TIA za wszelkie wskazówki ...

Odpowiedz

40

Potrzebny jest do tego właściwość zależność:

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

Gdy to zrobisz, możesz powiązać pole do właściwości zależność:

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

Za to do pracy trzeba wymienić okna lub UserControl w jego openning tag i używać tej nazwy w ElementName parametr.

Za pomocą tego kodu, za każdym razem, gdy zmienisz właściwość po stronie kodowej, zmienisz pole tekstowe. Ponadto, gdy zaznaczysz/odznacz pole tekstowe, właściwość Dependency również się zmieni.

EDIT:

Łatwym sposobem utworzyć właściwość zależność jest wpisanie propdp urywek, który daje ogólny kod dla właściwości zależności.

Cały kod:

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

Wskazówki, jak tylko kod związany jest Dependency nieruchomości. Zarówno etykieta, jak i pole wyboru są z nią związane. Jeśli pole wyboru zmieni się, etykieta również się zmieni.

+0

Dzięki za odpowiedź. Wygląda na to, że "ElementName" był brakującym kluczowym składnikiem. – Number8

+0

Cieszę się, że mogę pomóc =) – Carlo

+2

To zadziała, ale nie jest prawdą, że "do tego potrzebna jest właściwość zależności". Zobacz rozwiązania poniżej ... wszystko, czego potrzebujesz to wszystko, do czego chcesz się zmusić. –

4

jeśli mają właściwość „myProperty” na swojej danych klasy, a następnie związać IsChecked takiego .... (konwerter nie jest obowiązkowe, ale czasami trzeba że)

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

Jeśli właściwość jest już logiczna, nie jest potrzebny konwerter. –

+0

tak, dlatego jego "opcjonalne" :-) –

+0
60

musisz dokonać dwukierunkowy Oprawa:

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

Dzięki Thomas, który posortował to dla mnie, użyłem własności Content. – Spidey

1

Powinno być łatwiejsze.Wystarczy użyć:

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

Witam to jest mój pierwszy raz delegowania więc proszę o cierpliwość: moja odpowiedź było stworzenie prostego właściwość:

 public bool Checked 
     { get; set; } 

Następnie, aby ustawić kontekst danych pole wyboru (tzw CB1)

cb1.DataContext = this; 

Następnie do wiązania proerty IsChecked go w XAML

IsChecked="{Binding Checked}" 

Kod jest tak:

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

Działa to dla mnie (niezbędny kod obejmowała tylko wypełnić bardziej do swoich potrzeb):

W XAML kontrola użytkownika zdefiniowano:

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

W kodzie za 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(....); 
    } 

} 

Gdzieś w roztworze klasa MyViewModel definiuje

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