视觉状态和自定义依赖项属性 (MVVM)

本文关键字:属性 MVVM 依赖 状态 自定义 视觉 | 更新日期: 2023-09-27 18:36:32

我试图向按钮添加依赖属性。我的标题视图中有几个按钮,单击它们会在不同视图之间更改 ContentControl 中的内容。所有这些都很好用。我希望单击的按钮具有与其他按钮不同的前景色,并且看起来我需要添加依赖项属性。我想我已经准备好了所有部分,但不知道如何让它们一起工作。

我的视图模型中有一个名为 ViewState 的字符串属性,该属性会根据单击的按钮而变化。属性正在更改,当它发生时,我正在调用 RaisePropertyChanged。需要执行哪些操作才能绑定其他依赖项属性?我正在从WinForm世界过渡,并试图在精神上将它们拼凑在一起,但有点挣扎。

这是我到目前为止所拥有的:

    <Style TargetType="{x:Type Button}" x:Key="LocalButtonTemplate">
        <Setter Property="Foreground" Value="White" />
        <Setter Property="Background" Value="{x:Null}" />
        <Setter Property="FontFamily" Value="Segoe UI" />
        <Setter Property="FontSize" Value="18" />
        <Setter Property="Cursor"  Value="Hand" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border x:Name="outerBorder" Background="{TemplateBinding Background}" Margin="4">
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup x:Name="ViewState">
                                <VisualState x:Name="Dashboard">
                                    <Storyboard>
                                        <ColorAnimation Duration="0:0:0.1" To="Yellow"
                                            Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                                            Storyboard.TargetName="contentPresenter"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="AccountTables">
                                    <Storyboard>
                                        <ColorAnimation Duration="0:0:0.1" To="Red"
                                            Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                                            Storyboard.TargetName="contentPresenter"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="Normal">
                                    <Storyboard>
                                        <ColorAnimation Duration="0:0:0.1" To="Purple"
                                            Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                                            Storyboard.TargetName="contentPresenter"/>
                                    </Storyboard>
                                </VisualState>
                                <VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <ColorAnimation Duration="0:0:0.1" To="#35A84D"
                                            Storyboard.TargetProperty="(TextElement.Foreground).(SolidColorBrush.Color)"
                                            Storyboard.TargetName="contentPresenter"/>
                                    </Storyboard>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Grid>
                            <Border x:Name="Background" BorderBrush="Transparent">
                                <Grid>
                                    <ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}"
                                                      HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                                      VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                                      Margin="4,5,4,4"/>
                                </Grid>
                            </Border>
                        </Grid>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

我的按钮:

    <dxwuii:SplitPanel Margin="0,10,10,10" HorizontalAlignment="Right" Grid.Column="2" ItemSpacing="0" Orientation="Horizontal" ItemSizeMode="AutoSize" >
        <Button Command="{Binding SendViewModelNameCommand, Mode=OneTime}" CommandParameter="AccountTablesViewModel" Style="{StaticResource LocalButtonTemplate}">Express Tables</Button>
        <Button Command="{Binding SendViewModelNameCommand, Mode=OneTime}" CommandParameter="MappingViewModel" Style="{StaticResource LocalButtonTemplate}">Item Mapping</Button>
        <Button Command="{Binding SendViewModelNameCommand, Mode=OneTime}" CommandParameter="ReportsViewModel" Style="{StaticResource LocalButtonTemplate}">Reports</Button>
        <Button Command="{Binding SendViewModelNameCommand, Mode=OneTime}" CommandParameter="PostBalancesViewModel" Style="{StaticResource LocalButtonTemplate}">Post Balances</Button>
    </dxwuii:SplitPanel>

依赖属性类:

namespace MyAppName.Model
{
    public class StateManager : DependencyObject
    {
        public static string GetVisualStateProperty(DependencyObject obj)
        {
            return (string)obj.GetValue(VisualStatePropertyProperty);
        }
        public static void SetVisualStateProperty(DependencyObject obj, string value)
        {
            obj.SetValue(VisualStatePropertyProperty, value);
        }
        public static readonly DependencyProperty VisualStatePropertyProperty =
            DependencyProperty.RegisterAttached(
            "VisualStateProperty",
            typeof(string),
            typeof(StateManager),
            new PropertyMetadata((dependencyObject, args) =>
            {
                var frameworkElement = dependencyObject as FrameworkElement;
                if (frameworkElement == null)
                    return;
                VisualStateManager.GoToState(frameworkElement, (string)args.NewValue, true);
            }));
    }
}

视觉状态和自定义依赖项属性 (MVVM)

在每个按钮上设置TagAttached属性,如下所示。 Tag值将是单击按钮时应转到的VisualState值。

  <Button Tag="AcountTables" local:StateManager.VisualStateProperty="{Binding YOURVIEWMODELPROPERTY}" Command="{Binding SendViewModelNameCommand, Mode=OneTime}" CommandParameter="AccountTablesViewModel" Style="{StaticResource LocalButtonTemplate}">Express Tables</Button>

更新您的AttachedProperty,例如:

        public static readonly DependencyProperty VisualStatePropertyProperty =
        DependencyProperty.RegisterAttached(
        "VisualStateProperty",
        typeof(string),
        typeof(StateManager),
        new PropertyMetadata((dependencyObject, args) =>
        {
            var frameworkElement = dependencyObject as FrameworkElement;
            if (frameworkElement == null)
                return;
            if (args.NewValue == frameworkElement.Tag.ToString())
            {
                VisualStateManager.GoToState(frameworkElement, (string)args.NewValue, true);
            }
            else
            {
                VisualStateManager.GoToState(frameworkElement, "Normal", true);
            }
        }));