我想创建一组togglebuttons,一次检查零或一个切换按钮。
如果我使用带有togglebutton样式的radiobutton,那么至少一个togglebutton将在特定的时间处理,我想允许选择不检查togglebutton。
我为togglebutton和以下togglebuttons创建了以下样式,但由于某种原因 togglebutton在调用时不会改变缺血性质。
<Window x:Class="ClearMvvmDeltaItem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:Model="clr-namespace:ClearMvvmDeltaItem.Model" Title="MainWindow"
Height="300"
Width="300"
DataContext="{Binding Main, Source={StaticResource Locator}}">
<Window.Resources>
<Model:NotConverter x:Key="NotConverter" />
<Style TargetType="{x:Type CheckBox}">
<Style.Triggers>
<DataTrigger Value="False">
<DataTrigger.Binding>
<MultiBinding Converter="{StaticResource NotConverter}" UpdateSourceTrigger="PropertyChanged">
<Binding RelativeSource="{RelativeSource Mode=Self}" Path="Name"></Binding>
<Binding Path="CurrentCheckedItem"></Binding>
</MultiBinding>
</DataTrigger.Binding>
<DataTrigger.Setters>
<Setter Property="Background" Value="Red"></Setter>
<Setter Property="IsChecked" Value="False"></Setter>
</DataTrigger.Setters>
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<CheckBox x:Name="first" Content="First"
Command="{Binding FirstCheckedChanged}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Name}"
IsChecked="{Binding IsFirstChecked }"
>
</CheckBox>
<CheckBox x:Name="second" Command="{Binding SecondCheckedChanged}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Name}"
IsChecked="{Binding IsSecondChecked}"
Content="Second"
Grid.Row="1"></CheckBox>
<CheckBox x:Name="third" Content="Third" Grid.Row="2"
Command="{Binding ThirdCheckedChanged}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Name}"
IsChecked="{Binding IsThirdChecked}"
></CheckBox>
</Grid>
Viewmodel命令代码:
FirstCheckedChanged = new RelayCommand<string>(newName =>
{
if (_isFirstChecked)
CurrentCheckedItem = newName;
});
SecondCheckedChanged = new RelayCommand<string>(newName =>
{
if (_isSecondChecked)
CurrentCheckedItem = newName;
});
ThirdCheckedChanged = new RelayCommand<string>(newName =>
{
if (_isThirdChecked)
CurrentCheckedItem = newName;
});
调用datatrigger是因为我可以看到相关togglebuttons的背景颜色变为红色但是缺陷属性根本不受影响。
...谢谢
答案 0 :(得分:2)
就个人而言,我会使用ListBox
并设置样式,以便项目为ToggleButtons
<Style x:Key="ToggleButtonListBoxStyle" TargetType="{x:Type ListBox}">
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="KeyboardNavigation.DirectionalNavigation" Value="Cycle" />
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="2, 2, 2, 0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Border Background="Transparent">
<ToggleButton Content="{TemplateBinding ContentPresenter.Content}"
IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Style>
<ListBox ItemsSource="{Binding MyOptions}"
SelectedItem="{Binding CurrentCheckedItem}"
Style="{StaticResource ToggleButtonListBoxStyle}"/>
这样,一次只能切换一个按钮,您可以取消选中CurrentCheckedItem
,使null
等于ToggleButton
。
它还会稍微清理您的代码,因为您不需要跟踪3个单独的RelayCommands
来跟踪选择更改的时间。
作为旁注,原始代码无法正常工作,因为控件的<Tag>
中设置的属性优先于DataTrigger
中设置的属性。要使其工作,您必须将默认值(绑定)设置为<Style>
中的设置器。您可以了解有关依赖属性优先级here的更多信息。
答案 1 :(得分:1)
编程严格的MVVM并不总是可行的......这里和那里的一点解决方法没有错。这就是我解决它的方法(不使用单选按钮或列表框)。这是从共享的togglebutton点击事件调用的,传递按钮名称:
private void ToggleToolBarButtons(string button)
{
foreach (Object o in this.stkToolBar.Children)
{
if (o.GetType() == typeof(ToggleButton))
{
ToggleButton t = o as ToggleButton;
if (t.Name != button)
t.IsChecked = false;
else
t.IsChecked = true;
}
}
}
答案 2 :(得分:0)
我相信如果您在其定义(通过该绑定完成)中对复选框的IsChecked属性应用特定值,则会忽略您尝试通过样式应用的值。
鉴于您的复选框都绑定到视图模型属性,最简单的方法是更新这些视图模型属性而不是使用触发器。因此,将FirstCheckboxChecked属性设置为true,也会将SecondCheckboxChanged和ThirdCheckboxChanged属性更新为false,并将其传递给复选框本身。