2010-03-30 9 views
9

Listbox'ın MultiSelect modu kullanılarak this answer benzeri bir ListBox'ta ItemTemplate olarak kullanılan ToggleButtons listesi var. Ancak, en az bir öğenin her zaman seçildiğinden emin olmalıyım.ToggleButton öğesinin IsEnabled ayarlanmadan geçişini nasıl engelleyebilirim

ListBox'tan yalnızca bir öğe ListBox.SelectionChanged olayındaki ListBox'ın SelectedItems koleksiyonuna geri ekleyerek uygun davranışı elde edebilirim ancak ToggleButton hala değiştirilmiş durumundan dışarı taşınıyor, bu yüzden daha önce onu durdurmam gerektiğini düşünüyorum süreç.

Düğme şablonlarını yeniden yapmak zorunda kalmadan Etkin görsel stili ile kalmayı tercih ettiğim için Son düğmedeki IsEnabled = "False" ayarını seçmeden bunu yapmak istiyorum. Herhangi bir fikir?

cevap

28

Sen taban uygulamasını demeyerek, eyalet geçiş önlemek için OnToggle yöntemi geçersiz kılabilirsiniz:

public class LockableToggleButton : ToggleButton 
{ 
    protected override void OnToggle() 
    { 
     if (!LockToggle) 
     { 
      base.OnToggle(); 
     } 
    } 

    public bool LockToggle 
    { 
     get { return (bool)GetValue(LockToggleProperty); } 
     set { SetValue(LockToggleProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for LockToggle. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty LockToggleProperty = 
     DependencyProperty.Register("LockToggle", typeof(bool), typeof(LockableToggleButton), new UIPropertyMetadata(false)); 
} 
+0

teşekkürler. Bunu deneyeceğim. –

+3

Harika çözüm. – Ross

1

Bu hackey, ancak özel kod istemiyorsanız her zaman özelliğini kullanabilirsiniz " IsHitTestVisible ", onları işaretlemelerini istemediğinizde, IsHitTestVisible öğesini false değerine eşit olarak ayarlamanız yeterlidir. Ancak, kontrole sekme yapabilir ve boşluk çubuğunu kullanarak geçiş yapabilirler.

+0

Ayrıca, bir kullanıcı kilitliyken geçiş yapmaya çalıştığında sesli * ding * sesini yapmak istenebilir. IsHitTestVisible kullanımı, bunu elde etmenize izin vermez. – jpierson

+0

"IsTabStop =" False "işlevini kullanarak kullanıcının düğmeyi tıklatmasını önleyebilirsiniz. Bu çözümü, XAML'de sağlanabilir, MVVM dostu ve herhangi bir özel kod gerektirmediğinden kabul edilen cevap üzerinde tercih ederim. Birden fazla yerde uygulamanız gerekirse bir stil kullanılabilir. –

3

Bunun yerine RadioButtons'u kullanmayı denediniz mi? Normalde başka bir tane seçilmeden seçimi iptal edilemez. Zaten sadece BasedOn="{x:Type ToggleButton}" yapmak, bunun için bir Style varsa,

<RadioButton Style="{StaticResource {x:Type ToggleButton}}"/> 

Veya: Aynı zamanda bir ToggleButton gibi görünmek tarz olabilir. Visual Studio Editor ilk durumda bir hata gösterir, ancak derler ve iyi çalışır.

1

Thomas'ın cevabı iyi çalışıyor, ancak fazladan bağımlılık özelliğine ihtiyacınız yok. Geçiş düğmesindeki sınıfınız varsa, OnToggle yöntemini geçersiz kılabilirsiniz ve ViewModel'deki IsChecked bağlı özelliğini değiştirirseniz, düğmeniz doğru bir şekilde güncellenir.

Xaml:

<myControls:OneWayFromSourceToTargetToggle x:Name="MyCustomToggleButton" 
              Command="{Binding Path=ToggleDoStuffCommand}" 
              CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}}" 
              IsChecked="{Binding Path=ToggleIsCheckedConditionVar, 
                   Mode=OneWay}" 
              /> 

Eklendi ToggleButton Sınıf: doğru veya yanlış olarak ViewModel sadece set bool ToggleIsCheckedCondition içinde Sonra

public class OneWayFromSourceToTargetToggle : ToggleButton 
{ 
    /// <summary> 
    /// Overrides the OnToggle method, so it does not set the IsChecked Property automatically 
    /// </summary> 
    protected override void OnToggle() 
    { 
     // do nothing 
    } 
} 

. Bu, iyi MVVM uygulamalarını izlediğiniz için bunu yapmanın iyi bir yoludur.

ViewModel:

public bool ToggleIsCheckedCondition 
{ 
    get { return _toggleIsCheckedCondition; } 
    set 
    { 
     if (_toggleIsCheckedCondition != value) 
     { 
     _toggleIsCheckedCondition = value; 
     NotifyPropertyChanged("ToggleIsCheckedCondition"); 
     } 
    } 
} 

public ICommand ToggleDoStuffCommand 
{ 
    get { 
     return _toggleDoStuffCommand ?? 
       (_toggleDoStuffCommand = new RelayCommand(ExecuteToggleDoStuffCommand)); 
     } 
} 

private void ExecuteToggleDoStuffCommand(object param) 
{ 
    var btn = param as ToggleButton; 
    if (btn?.IsChecked == null) 
    { 
     return; 
    } 
    // has not been updated yet at this point 
    ToggleIsCheckedCondition = btn.IsChecked == false; 

    // do stuff 

    } 
}