ContentControl在两个按钮之间切换

Rya*_* S. 2 c# wpf

整晚都在敲打我的脑袋.我想要做的就是有一个内容控件,可以根据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)

B.K*_*.K. 5

有很多方法可以实现这一目标(这就是WPF的美妙之处); 但是,在我个人看来,如果你只是使用一个源于它的控件,那么你将更少地"反对谷物" ToggleButton,例如RadioButton,特别是因为你希望它在XAML中全部完成.重要的是不要通过视觉效果来考虑任何控件,而应考虑它们的功能.我以前做过一些令人难以置信的事情RadioButton,所以这是我要展示的第一件事; 但是,常规按钮方法包含在本答案的后半部分中.

以下是两种方法(RadioButtonButton)的完整示例,完全在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可见.这必须以当地风格完成,因为我们需要将其传递ElementNameBinding.因此,当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.你可以通过EventTriggerClick事件一起完成类似的事情......但是,还有更多工作要做. IsPressed可能会出现像一个不错的选择,但问题是,一旦你按下按钮时,其他人会出现几乎是瞬间,以及一个将已IsPressed设定为true几乎瞬间.所以,你最终会发现这种循环行为,似乎没有任何事情发生.请注意,我使用Grid这些按钮放在彼此的顶部,默认情况下我想要在顶部显示,这样我就不必担心默认的可见性或焦点.但是,您可以使用任何其他面板,只需将Visibility默认情况下要隐藏的按钮设置为Collapsed.

如果您不想使用多个控件(在这种情况下为两个按钮),您还可以Content根据条件设置按钮的属性DataTrigger以显示不同的文本.你必须确保你Command妥善处理.

  • 很好的答案.+1.无关的问题:您使用什么软件来制作预览? (2认同)
  • @HighCore我使用LICEcap(http://www.cockos.com/licecap/)和Screen To Gif(https://screentogif.codeplex.com/).SG实际上是在WPF中创建的,但在某些情况下它的稳定性稍差. (2认同)
  • 谢谢,我会试一试;) (2认同)