开发环境
VS2022
.net6
MVVMToolkit
实现思路
在状态管理器下,不同状态设置设置不同的图标和属性,以使状态能清晰分辨。
代码实现
以下为WINUI下Style实现示例,WPF可作参考:
<Style x:Key="DynamicIconButtonStyle" TargetType="Button"> <Setter Property="FocusVisualMargin" Value="-3" /> <Setter Property="Height" Value="64" /> <Setter Property="Width" Value="278" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Border x:Name="border" Background="#76C265" CornerRadius="8"> <!-- 主布局 --> <StackPanel x:Name="ContentStack" HorizontalAlignment="Center" Orientation="Horizontal"> <!-- 正常状态图标(通过 Content 传入) --> <ContentPresenter x:Name="NormalIconPresenter" Margin="0,0,8,0" Content="{TemplateBinding Content}" /> <!-- 禁用状态图标(通过 Tag 传入) --> <ContentPresenter x:Name="DisabledIconPresenter" Content="{TemplateBinding Tag}" Visibility="Collapsed" /> </StackPanel> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalIconPresenter" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DisabledIconPresenter" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> <VisualState x:Name="Disabled"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="border" Storyboard.TargetProperty="Background"> <DiscreteObjectKeyFrame KeyTime="0" Value="#E8EBED" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="NormalIconPresenter" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DisabledIconPresenter" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> </ObjectAnimationUsingKeyFrames> <!--<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonText" Storyboard.TargetProperty="Foreground"> <DiscreteObjectKeyFrame KeyTime="0" Value="#A8A9AB" /> </ObjectAnimationUsingKeyFrames>--> </Storyboard> </VisualState> </VisualStateGroup> </VisualStateManager.VisualStateGroups> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
Page中Button代码如下:
<Button Margin="0,0,32,0" HorizontalAlignment="Center" Command="{x:Bind ViewModel.ReRegistrationCommand}" FontSize="32" Style="{StaticResource DynamicIconButtonStyle}" Visibility="{x:Bind ViewModel.CurCase.IsCBCT, Converter={StaticResource ReverseBooleanToVisibilityConverter}}"> <Button.Content> <StackPanel VerticalAlignment="Center" Orientation="Horizontal"> <FontIcon FontFamily="{StaticResource PatientPosition}" FontSize="32" Glyph="" /> <TextBlock Foreground="White" Text="重新配准" /> </StackPanel> </Button.Content> <Button.Tag> <StackPanel VerticalAlignment="Center" Orientation="Horizontal"> <FontIcon FontFamily="{StaticResource PatientPosition}" FontSize="32" Glyph="" /> <TextBlock Foreground="#A8A9AB" Text="重新配准" /> </StackPanel> </Button.Tag> </Button>
在VM中调用如下,button是否可用通过执行CanExecute来决定。
[RelayCommand(CanExecute = nameof(CanReRegistration))]private void ReRegistration() { UploadingSurgicalPlan.UploadDruingSurgery(curCase, true); }
以上代码中涉及的CanReRegistration如下:
private bool CanReRegistration() { return BluetoothConnect && CurCase.Stage >= CaseStage.Uploaded; }
CanReRegistration为CanExecute执行的方法。