整晚都在敲打我的脑袋.我想要做的就是有一个内容控件,可以根据ViewModel中的布尔值在显示两个不同的按钮之间切换.
基本上我有一个任务在后台运行,带有取消按钮.一旦你点击取消并且任务停止,取消按钮应该变为后退按钮.这是两个单独的按钮元素,而不仅仅是更改单个按钮的属性.我正在使用MahApps TransitioningContentControl,所以我希望能够使用转换.
如果这大部分可以在XAML中完成,我会很惊讶.我真的不想为一个简单的东西添加一堆样板代码.
编辑:这是代码片段.没有太多因为我刚刚删除了所有无效的内容.
<Controls:TransitioningContentControl x:Name="CancelBackButtonControl" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Height="80">
<Canvas>
<Button x:Name="CancelButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Style="{DynamicResource MetroCircleButtonStyle}" Height="80" IsCancel="True" Content="{StaticResource appbar_close}" BorderBrush="Black" Command="{Binding CancelCommand}"/>
<Button x:Name="GoBackButton" HorizontalAlignment="Left" VerticalAlignment="Top" Width="80" Style="{DynamicResource MetroCircleButtonStyle}" Height="80" IsCancel="True" Content="{StaticResource appbar_arrow_left}" BorderBrush="Black" Command="{Binding GoBackCommand}"/>
</Canvas>
</Controls:TransitioningContentControl>
Run Code Online (Sandbox Code Playgroud)
有很多方法可以实现这一目标(这就是WPF的美妙之处); 但是,在我个人看来,如果你只是使用一个源于它的控件,那么你将更少地"反对谷物" ToggleButton,例如RadioButton,特别是因为你希望它在XAML中全部完成.重要的是不要通过视觉效果来考虑任何控件,而应考虑它们的功能.我以前做过一些令人难以置信的事情RadioButton,所以这是我要展示的第一件事; 但是,常规按钮方法包含在本答案的后半部分中.
以下是两种方法(RadioButton和Button)的完整示例,完全在XAML中完成:
预习:

码:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type RadioButton}" x:Key="FlatRadioButtonStyle">
<Setter Property="Width" Value="100"/>
<Setter Property="Background" Value="#FF346FD6"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Padding" Value="5,2,5,3"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type RadioButton}">
<Border Background="{TemplateBinding Background}"
Width="{TemplateBinding Width}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}">
<ContentPresenter Content="{TemplateBinding Content}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FF6696E9"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<RadioButton x:Name="BackButton" Content="Back">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}" BasedOn="{StaticResource FlatRadioButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=CancelButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
<RadioButton x:Name="CancelButton" Content="Cancel" IsChecked="True">
<RadioButton.Style>
<Style TargetType="{x:Type RadioButton}" BasedOn="{StaticResource FlatRadioButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsChecked, ElementName=BackButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</RadioButton.Style>
</RadioButton>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
大多数资源样式代码都是视觉样式和模板,专注于使单选按钮看起来像常规按钮,因此它并不重要.我们将关注的领域是Triggers.您会注意到,在资源样式中,我确保RadioButton在检查时它会崩溃.但是,在每个按钮的本地样式中,我确保RadioButton在检查另一个按钮时,它会使当前RadioButton可见.这必须以当地风格完成,因为我们需要将其传递ElementName到Binding.因此,当RadioButton检查时,它会折叠并使另一个RadioButton可见.你还会注意到我默认选中了我想要隐藏的按钮.显然,你可以用绑定来连接它.
类似的方法可以应用于常规按钮:
预习:

码:
<Window x:Class="Sample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Style TargetType="{x:Type Button}" x:Key="ToggleButtonStyle">
<Setter Property="Width" Value="100"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Style.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Visibility" Value="Collapsed"/>
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid>
<Button x:Name="CancelButton" Content="Cancel">
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ToggleButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=BackButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button x:Name="BackButton" Content="Back">
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ToggleButtonStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsFocused, ElementName=CancelButton}" Value="True">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
在这里,IsChecked我正在努力IsFocused.你可以通过EventTrigger和Click事件一起完成类似的事情......但是,还有更多工作要做. IsPressed可能会出现像一个不错的选择,但问题是,一旦你按下按钮时,其他人会出现几乎是瞬间,以及一个将已IsPressed设定为true几乎瞬间.所以,你最终会发现这种循环行为,似乎没有任何事情发生.请注意,我使用Grid这些按钮放在彼此的顶部,默认情况下我想要在顶部显示,这样我就不必担心默认的可见性或焦点.但是,您可以使用任何其他面板,只需将Visibility默认情况下要隐藏的按钮设置为Collapsed.
如果您不想使用多个控件(在这种情况下为两个按钮),您还可以Content根据条件设置按钮的属性DataTrigger以显示不同的文本.你必须确保你Command妥善处理.