代码之家  ›  专栏  ›  技术社区  ›  Bryan Anderson

如何防止在未设置IsEnabled的情况下切换ToggleButton

  •  9
  • Bryan Anderson  · 技术社区  · 16 年前

    我有一个ToggleButtons列表,在一个类似于的列表框中用作ItemTemplate this answer 使用列表框的多选模式。但是,我需要确保至少有一个项目总是被选中。

    我不想在最后一个选中的按钮上设置IsEnabled=“False”,因为我更希望保持启用的视觉样式,而不必重做按钮模板。有什么想法吗?

    4 回复  |  直到 9 年前
        1
  •  34
  •   Thomas Levesque    16 年前

    您可以覆盖 OnToggle 方法通过不调用基实现来防止切换状态:

    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));
    }
    
        2
  •  7
  •   Joachim Mairböck    10 年前

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

    或者,如果你已经有了 Style 为了它,就让它 BasedOn="{x:Type ToggleButton}" . 请注意,VisualStudio编辑器在第一种情况下显示错误,但它编译并正常工作。

        3
  •  2
  •   viggity    16 年前

    这是hackey,但是如果您不需要自定义代码,您可以始终使用属性“ishitettvisible”,当您不希望他们取消选中它时,只需将ishitettvisible设置为false。但是,他们可能可以使用空格键对控件进行制表符切换。

        4
  •  1
  •   Jim Kniest    9 年前

    Thomas的答案很好,但是您甚至不需要额外的依赖属性。如果让类inherit from ToggleButton重写OnToggle方法,并且更改ViewModel上的IsChecked绑定属性,则按钮将正确更新。

    Xaml编号:

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

    添加了ToggleButton类:

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

    然后在ViewModel中将bool-ToggleIsCheckedCondition设置为true或false。这是一个很好的方法,因为您遵循良好的MVVM实践。

    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
    
       }
    }
    
        5
  •  0
  •   Peter Lamberg qed    6 年前

    在@Joachim Mairbck的伟大答案中添加一点,以防您想以编程方式执行相同的操作:

    new RadioButton {
        ...
        GroupName = "myButtonGroup"
        Style = Application.Current.TryFindResource(typeof(ToggleButton)) as Style
        ...
    }