2014-12-19 92 views
0

我有一个带有一些按钮的菜单栏导航到不同部分的WPF应用程序。在WPF中处理按钮状态

所有按钮都具有VisualState属性的样式,因此它们都具有Normal,OnMouseOver和Pressed状态不同的样式。所有按钮,一旦按下,在ModelView上执行一个命令。

我想要的是每次按下按钮时,首先它会保持按下状态,直到按下另一个按钮,其次,可以在ModelView侧执行的Command事件中更改按钮状态。

验证码:

<Style x:Key="MainButtonStyle" TargetType="Button"> 
     <Setter Property="Width" Value="120"/> 
     <Setter Property="Height" Value="60"/> 
     <Setter Property="Margin" Value="5"/>    
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type Button}"> 
        <Grid Background="White" x:Name="ButtonGrid"> 
         <VisualStateManager.VisualStateGroups> 
          <VisualStateGroup x:Name="CommonStates"> 
           <VisualState x:Name="Normal"/> 
           <VisualState x:Name="MouseOver"> 
            <Storyboard>            
             <ColorAnimation Duration="0:0:0.3" Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="Background.Color" To="Cyan"/> 
            </Storyboard> 
           </VisualState> 
           <VisualState x:Name="Pressed"> 
            <Storyboard> 
             <ColorAnimation Duration="0:0:0.2" Storyboard.TargetName="ButtonGrid" Storyboard.TargetProperty="Background.Color" To="DarkSalmon"/> 
            </Storyboard> 
           </VisualState> 
          </VisualStateGroup> 
         </VisualStateManager.VisualStateGroups> 
        </Grid> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

使用样式的按钮:

<ItemsControl Margin="10" Grid.Column="1" Grid.RowSpan="2" ItemsSource="{Binding HeaderButtons}"> 
      <ItemsControl.ItemTemplate> 
       <DataTemplate> 
        <Button Style="{StaticResource MainButtonStyle}" Content="{Binding content}" 
          Command="{Binding DataContext.ChangePageContainerCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
          CommandParameter="{Binding containerType}"/> 
       </DataTemplate> 
      </ItemsControl.ItemTemplate>     
     </ItemsControl> 

,我认为该模型视图是不相关的,因为它在按钮上的VisualState,因为我不知道什么如何将它传递给Button调用者的引用(作为参数或其他?)。

我在其他帖子中看到人们推荐使用ToggleButton代替Button并将IsChecked设置为true,但我不知道应该在哪里设置该属性,我的意思是,我应该将它设置为XAML还是代码?如何?

回答

1

我想是每一个按钮被按下时,首先保持按下状态,直到另一个按钮被按下

你想要的是一组RadioButton S,但可能是那些看起来像正常Button s。下面是一些RadioButton s表示看起来有点像Button个小小的例子:

<StackPanel Orientation="Horizontal"> 
    <StackPanel.Resources> 
     <Style TargetType="{x:Type RadioButton}"> 
      <Setter Property="BorderBrush" Value="Blue" /> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="{x:Type RadioButton}"> 
         <Border Name="Border" CornerRadius="4" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="2" Padding="10, 5" VerticalAlignment="Top" Margin="0,0,5,0"> 
          <ContentPresenter /> 
         </Border> 
         <ControlTemplate.Triggers> 
          <Trigger Property="IsMouseOver" Value="True"> 
           <Setter TargetName="Border" Property="Border.Background" Value="LightBlue" /> 
          </Trigger> 
          <Trigger Property="IsChecked" Value="True"> 
           <Setter TargetName="Border" Property="Border.Background" Value="LightGreen" /> 
           <Setter TargetName="Border" Property="Border.BorderBrush" Value="Green" /> 
          </Trigger> 
         </ControlTemplate.Triggers> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </StackPanel.Resources> 
    <RadioButton Content="Button 1" /> 
    <RadioButton Content="Button 2" /> 
    <RadioButton Content="Button 3" /> 
</StackPanel> 

请注意,我已经添加使用基本Trigger小号......用VisualStateManager的一些基本状态功能只是这里不必要的,似乎是给你带来额外的问题。当我们编写需要明确分离状态的复杂UserControlCustomControl时,VisualStateManager真的出现了。为了您的简单目的,您应该只使用Trigger

是否可以在ModelView侧执行的Command事件中更改按钮状态?

您的第二个问题的答案已经回答了很多次,之后UI将不会在这里再次讨论它。只要说你可以在How to bind RadioButtons to an enum?问题中找到详细信息(或许多其他在线资源)。总之,您需要定义一个enum,声明一个EnunmToBoolConverter,使您能够将您的enumRadioButtonbool IsChecked属性绑定。然后,您将能够设置每个Button从视图模型中选择或不选择。