2011-12-30 12 views
10

Im kırık Binding. Benim elde etmek istediğim davranış, CheckBox'un ViewModel'i (ve dolayısıyla Expander'ı da) etkilemesini sağlamaktır, ancak başka bir şekilde bağlı değildir.WPF Tek Yönlü 2 farklı WPF ViewModel bir CheckBox.IsChecked ve Expander.IsExpanded aynı özelliğe denetimleri bağlamak için çalışıyor

<Window x:Class="WpfApplication9.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Expander IsExpanded="{Binding IsChecked, Mode=OneWay}"> 
     <Expander.Header> 
      <CheckBox IsChecked="{Binding IsChecked}" Content="Is Checked"/> 
     </Expander.Header> 
     <TextBlock Text="Expanded!"/> 
    </Expander> 
</Window> 

ve Kod:

Şimdi
using System.ComponentModel; 
using System.Windows; 

namespace WpfApplication9 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
      DataContext = new ViewModel(); 
     } 
    } 

    public class ViewModel: INotifyPropertyChanged 
    { 
     private bool _isChecked; 
     public bool IsChecked 
     { 
      get { return _isChecked; } 
      set 
      { 
       _isChecked = value; 
       NotifyPropertyChange("IsChecked"); 
      } 
     } 

     protected void NotifyPropertyChange(string PropertyName) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(PropertyName)); 
     } 

     public event PropertyChangedEventHandler PropertyChanged = delegate { }; 
    } 
} 

benim sorunum, en kısa sürede genişletmek için Expander'da tıklayarak olarak/çöküşü İşte

Checkbox Checked -> ViewModel property set to frue -> Expander.Expand 
Checkbox Unchecked -> ViewModel property set to false -> Expander.Collapse 
Expander Expanded -> Nothing else affected 
Expander Collapsed -> Nothing else affected 

XAML var: şey gibi Bu, Bağlanma çalışmayı durdurur gibi görünüyor. Herkes bana bunun neden olduğunu açıklayabilir mi ve bunu nasıl başarabilirim? Şimdiden teşekkürler!

cevap

10

size Expander'da senin UpdateSourceTriggerExplicit için ayarlayarak bunu yapabileceğini keşfetti Yeni Cevap

o. Bu, bağlamayı İki Yönlü olarak tutar, ancak Kaynağı açıkça güncelleştirmediğiniz sürece, Kaynak'ı hiçbir zaman güncellemediğiniz için Kaynak'ı hiçbir zaman günceller. böylece yorumların altında benim eski cevabını bırakarak

<Expander IsExpanded="{Binding IsChecked, UpdateSourceTrigger=Explicit}"> 
    <Expander.Header> 
     <CheckBox IsChecked="{Binding IsChecked}" Content="Is Checked"/> 
    </Expander.Header> 
    <TextBlock Text="Expanded!"/> 
</Expander> 

mantıklı ve hala hissediyorum çünkü görünümü özgü kod bir görünüm :)


kod-arkasında gidiyor ile sorun yoktur bu yana Şahsen

Eski Cevap Ben genişletici en IsExpanded değerini ayarlamak için bir CheckBox click olayı kullanarak hiçbir sorun bakın Görünüm Özgü koddur.

private void MyCheckBox_Click(object sender, RoutedEventArgs e) 
{ 
    MyExpander.IsExpanded = ((CheckBox)sender).IsChecked.GetValueOrDefault(); 
} 

hale getirebilirsin bu daha da jenerik isimler kaldırılması ve CheckBox ile ilişkili Expander'daki bulmak için Görsel Ağacı giderek. Burada arkada kodu herhangi kaçınmak istiyorsanız bazı Visual Tree Helpers I built

private void CheckBox_Click(object sender, RoutedEventArgs e) 
{ 
    var chk = (CheckBox)sender; 
    var expander = VisualTreeHelpers.FindAncestor<Expander>(chk); 

    if (expander != null) 
     expander.IsExpanded = chk.IsChecked.GetValueOrDefault(); 
} 
+0

Başlıklarında Onay Kutusundaki en az 6 Genişletici ile bir görünüm oluşturuyorum. Çok fazla kodu ve hiç bir kod kullanmamayı tercih ediyorum çünkü görüşün esnekliğini azaltır. –

+0

@HighCore Birden çok Genişletme/Onay Kutunuz varsa, bunlar için muhtemelen varsayılan bir stiliniz vardır ve Tıklat olayını stilde bir EventSetter olarak ayarlayabilirdiniz. Bu CheckBox ile ilişkili Expander'ı bulmak için görsel ağacında gezinmek için bir şey kullanırdım ve adlandırılmış değerleri kullanmanız gerekmeyecekti. – Rachel

+0

@HighCore Güncellenmiş cevabımı görün. – Rachel

1

araçlar bölümündeki genişletici etkiler (ama tersi değil) daha sonra normal olarak genişletici bağlamak ve onay kutusunu OneWayToSource kullanmak istiyorsanız:

: bunu sağlayacak

<Window x:Class="WpfApplication9.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525"> 
    <Expander IsExpanded="{Binding IsChecked}"> 
     <Expander.Header> 
     <CheckBox IsChecked="{Binding IsChecked, Mode=OneWayToSource}" Content="Is Checked"/> 
     </Expander.Header> 
     <TextBlock Text="Expanded!"/> 
    </Expander> 
</Window> 

onay kutusunu OneWayToSource kullanma

  • yatan özelliğini değiştirmek (ve bu nedenle de bu özelliğine bağlı genişletici etkiler) değişiklikler t yapmak diğer bileşenler tarafından etkilenmez
  • altta yatan mülkiyet
+1

Yapamam Bunu yapmak için onay kutusu burada birincil veri temsilidir.Her zaman ViewModel'deki değeri yansıtmalıdır. –

+0

@HighCore Bunu düşünene kadar bunu + 1'lemek üzereydim, yani düşündüm. Gerçi bu gerekli değilse güzel bir çözüm. – Rachel

+1

MSDN'ye göre, onay kutuları için varsayılan mod genellikle TwoWay'dır, ancak bunu açıkça yazmayı denediniz mi? "{Binding IsChecked, Mode = TwoWay}" –

1

, kendi ViewModel Expander ve CheckBox devletler arasındaki ayrılık derecesine ekleyebilirsiniz kullanarak bir örnek:

  private bool _isChecked; 
      public bool IsChecked 
      { 
       get { return _isChecked; } 
       set 
       { 
        _isChecked = value; 
        NotifyPropertyChange("IsChecked"); 
        IsExpanded = value; 
       } 
      } 

      private bool _isExpanded; 
      public bool IsExpanded 
      { 
       get { return _isExpanded; } 
       set 
       { 
        _isExpanded = value; 
        NotifyPropertyChange("IsExpanded"); 
       } 
      } 

    <Expander IsExpanded="{Binding IsExpanded}"> 
     <Expander.Header> 
      <CheckBox IsChecked="{Binding IsChecked}" Content="Is Checked" x:Name="cb"/> 
     </Expander.Header> 
     <TextBlock Text="Expanded!"/> 
    </Expander> 
+0

Evet, bunu son çare olarak düşündüm. –