2012-02-28 41 views
0

我想创建一组切换按钮,一次检查零个或一个切换按钮。选中零个或一个切换按钮的ToggleButton组

如果我使用带按钮式按钮的单选按钮,那么至少有一个按钮将在特定的时间被checke,并且我想允许没有选择按钮的选项被选中。

我创建了以下样式到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> 

视图模型的命令代码:

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的背景颜色变为红色,但物业器isChecked不以影响所有。

谢谢...

回答

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

0

我相信,如果你在它的定义,则值(您已通过绑定完成)应用特定的价值,您的复选框的财产器isChecked尝试通过以应用风格被忽略。

鉴于您的复选框都绑定到查看模型属性,它可能是最简单的更新它们只需更新这些视图模型属性,而不是使用触发器。因此,将FirstCheckboxChecked属性设置为true,也会将SecondCheckboxChanged和ThirdCheckboxChanged属性更新为false,并将其传递到复选框本身。

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