2015-10-29 3 views
1

Я хотел бы изменить вид кнопки после нажатия кнопки. Например, у меня есть два шаблона beforeClicking и afterClicking:Как изменить шаблоны после нажатия кнопки

<Style TargetType="Button"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="Button" x:Name="beforeClicking"> 
       <Border Name="border" Background="Transparent" BorderThickness="1" BorderBrush="Black"> 
        <ContentPresenter/> 
       </Border>      
      </ControlTemplate> 
      <!--It is not permitted, but that is pseudocode(what I want) 
      <ControlTemplate TargetType="Button" x:Name="afterClicking"> 
       <Border Name="border" Background="Transparent" BorderThickness="10" BorderBrush="Black"> 
        <ContentPresenter/> 
       </Border>      
      </ControlTemplate> 
      --> 
     </Setter.Value> 
    </Setter> 
</Style> 

То, что я хочу, когда кнопка не нажата, то шаблон beforeClicking должен быть постоянно используется и ничего (шаблон или вид) не должен быть изменен. Однако, если пользователь нажимает кнопку, то кнопка должна использовать шаблон afterClicking постоянно, и вид кнопки не должен изменяться.

Это при первом нажатии кнопки используется шаблон afterClicking. При втором нажатии кнопки используется шаблон beforeClicking. При третьем нажатии на кнопку используется шаблон afterClicking. При четвертом нажатии кнопки используется шаблон afterClicking. И так далее.

Я хотел бы получить такое поведение только с помощью XAML, поскольку используется подход MVVM.

Как добиться такого поведения?

ответ

1

Вы можете обрабатывать щелчок с помощью EventTrigger. В случае триггера вы предоставляете раскадровку, но в раскадровке вы не можете изменить шаблон.

Вы можете сделать это в приложенном собственности, но, глядя на вашем примере, вам не нужно, и более типично, вы бы повлиять на индивидуальные свойства:

<Style TargetType="Button"> 
    <Setter Property="BorderThickness" Value="1" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="Button"> 
       <Border Name="border" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Black"> 
        <ContentPresenter/> 
       </Border> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Style.Triggers> 
     <EventTrigger RoutedEvent="Click"> 
      <EventTrigger.Actions> 
       <BeginStoryboard> 
        <Storyboard> 
         <ThicknessAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness"> 
          <DiscreteThicknessKeyFrame Value="10" KeyTime="0" /> 
         </ThicknessAnimationUsingKeyFrames> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger.Actions> 
     </EventTrigger> 
    </Style.Triggers> 
</Style> 

== После обсуждения: ToggleButton версия: ==

<Window.Resources> 
    <Style TargetType="ToggleButton"> 
     <Setter Property="BorderThickness" Value="1" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="ToggleButton"> 
        <Border Name="border" Background="Transparent" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="Black"> 
         <ContentPresenter/> 
        </Border> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
     <Style.Triggers> 
      <Trigger Property="IsChecked" Value="True"> 
       <Setter Property="BorderThickness" Value="10" /> 
      </Trigger> 
     </Style.Triggers> 
    </Style> 
</Window.Resources> 
<Grid> 
    <ToggleButton>Hello World</ToggleButton> 
</Grid> 
+0

Он работает нормально, но если я нажимаю во второй раз, то шаблон кнопки не возвращается в исходное состояние. Пожалуйста, см. Мой обновленный ответ. – StepUp

+0

О, извините, неправильно понято; не понимал, что вы хотите «переключиться», подумал, что вы хотите, чтобы он держался. В таком случае вам лучше использовать ToggleButton? Затем вы можете связать свой BorderThickness с триггером свойства IsChecked. –

+0

, пожалуйста, напишите свой ответ о кнопке переключения, и я приму это. – StepUp

1

Если бы я тебя, я хотел бы использовать System.Windows.Interactivity.Behavior, а не EventTriggers, к сожалению EventTriggers единственный способ для вас, чтобы связать в XAML случае с операцией, единственная проблема заключается в том, что EventTriggers работает только с TriggerAction объектами, и вы не можете создать TriggerAction. Это потому, что это абстрактный класс, абстрактные методы которого являются внутренними и не переопределяемыми извне библиотеки PresentationFramework. Вот пример того, как подготовить свой класс Поведение:

public class ChangeTemplateBehavior : System.Windows.Interactivity.Behavior<Button> 
{ 
    public static readonly DependencyProperty ControlTemplate1Property = DependencyProperty.Register("ControlTemplate1", typeof(ControlTemplate), typeof(ChangeTemplateBehavior), new PropertyMetadata(default(ControlTemplate))); 

    public ControlTemplate ControlTemplate1 
    { 
     get 
     { 
      return (ControlTemplate)GetValue(ControlTemplate1Property); 
     } 
     set 
     { 
      SetValue(ControlTemplate1Property, value); 
     } 
    } 

    public static readonly DependencyProperty ControlTemplate2Property = DependencyProperty.Register("ControlTemplate2", typeof(ControlTemplate), typeof(ChangeTemplateBehavior), new PropertyMetadata(default(ControlTemplate))); 

    public ControlTemplate ControlTemplate2 
    { 
     get 
     { 
      return (ControlTemplate)GetValue(ControlTemplate2Property); 
     } 
     set 
     { 
      SetValue(ControlTemplate2Property, value); 
     } 
    } 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     this.AssociatedObject.Click += AssociatedObject_Click; 
    } 

    void AssociatedObject_Click(object sender, RoutedEventArgs e) 
    { 
     if (this.AssociatedObject.Template == this.ControlTemplate2) 
     { 
      this.AssociatedObject.Template = this.ControlTemplate1; 
     } 
     else 
     { 
      this.AssociatedObject.Template = this.ControlTemplate2; 
     } 
    } 
} 

А вот пример того, как написать код XAML:

<Window x:Class="StackoverflowHelpWPF5.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:[YOURLOCALNAMESPACEHERE]" 
     xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
     Title="MainWindow" Height="350" Width="525"> 
    <Window.Resources> 

     <ControlTemplate TargetType="Button" x:Key="beforeClicking"> 
      <Border Name="border" Background="Transparent" BorderThickness="1" BorderBrush="Black"> 
       <ContentPresenter/> 
      </Border> 
     </ControlTemplate> 

     <ControlTemplate TargetType="Button" x:Key="afterClicking"> 
      <Border Name="border" Background="Transparent" BorderThickness="10" BorderBrush="Black"> 
       <ContentPresenter/> 
      </Border>      
     </ControlTemplate> 

    </Window.Resources> 

    ... 

    <Button Template="{StaticResource beforeClicking}" > 
      <i:Interaction.Behaviors> 
       <local:ChangeTemplateBehavior ControlTemplate1="{StaticResource afterClicking}" ControlTemplate2="{StaticResource beforeClicking}"></local:ChangeTemplateBehavior> 
      </i:Interaction.Behaviors> 
    </Button> 
+0

, пожалуйста, напишите описание staticResources. Просто самый простой, но пример работы) – StepUp

+0

Просто добавил, взгляните на них;) –

+0

Спасибо :). Он работает нормально, однако, если я нажму второй раз, шаблон кнопки не будет возвращен в исходное состояние. – StepUp

Смежные вопросы