我有一个ToggleButtons列表,在ListBox中使用类似于this answer的ItemTemplate,使用Listbox的MultiSelect模式。但是我需要确保始终选择至少一个项目。
我可以从ListBox中获取正确的行为,只需在ListBox.SelectionChanged事件中将一个项目添加回ListBox的SelectedItems集合中,但我的ToggleButton仍然会移出其切换状态,所以我想我需要先在处理。
我想在没有在最后一个按钮上设置IsEnabled =“False”的情况下这样做,因为我更喜欢使用Enabled视觉样式,而不必重做我的按钮模板。有什么想法吗?
答案 0 :(得分:32)
您可以通过不调用基本实现来覆盖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));
}
答案 1 :(得分:3)
您是否尝试过使用RadioButtons?如果不选择另一个,通常无法取消选择。它的样式也可以看起来像ToggleButton:
<RadioButton Style="{StaticResource {x:Type ToggleButton}}"/>
或者,如果您已经拥有Style
,请将其设为BasedOn="{x:Type ToggleButton}"
。请注意,Visual Studio编辑器在第一种情况下显示错误,但它编译并正常工作。
答案 2 :(得分:1)
这是hackey,但如果您不想要自定义代码,则可以始终使用属性“IsHitTestVisible”,当您不希望它们取消选中时,只需将IsHitTestVisible设置为false即可。但是,他们可以使用空格键切换到控件并进行切换。
答案 3 :(得分:1)
托马斯的回答很好,但你甚至不需要额外的依赖属性。如果您的类继承自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
}
}
答案 4 :(得分:0)
在@Joachim-Mairböck的出色答案中添加了一些内容,以防您需要以编程方式执行相同操作:
new RadioButton {
...
GroupName = "myButtonGroup"
Style = Application.Current.TryFindResource(typeof(ToggleButton)) as Style
...
}