开发环境
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"><Borderx:Name="border"Background="#76C265"CornerRadius="8"><!-- 主布局 --><StackPanelx:Name="ContentStack"HorizontalAlignment="Center"Orientation="Horizontal"><!-- 正常状态图标(通过 Content 传入) --><ContentPresenterx:Name="NormalIconPresenter"Margin="0,0,8,0"Content="{TemplateBinding Content}" /><!-- 禁用状态图标(通过 Tag 传入) --><ContentPresenterx: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代码如下:
<ButtonMargin="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"><FontIconFontFamily="{StaticResource PatientPosition}"FontSize="32"Glyph="" /><TextBlock Foreground="White" Text="重新配准" /></StackPanel></Button.Content><Button.Tag><StackPanel VerticalAlignment="Center" Orientation="Horizontal"><FontIconFontFamily="{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执行的方法。