c# - 视觉状态和自定义依赖属性 (MVVM)

标签 c# wpf xaml mvvm

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

我的 View 模型中有一个名为 ViewState 的字符串属性,它会根据单击的按钮而变化。该属性正在发生变化,当它发生时我会调用 RaisePropertyChanged 。我需要做什么来绑定(bind)附加依赖属性?我正在从 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);
            }));
    }
}

最佳答案

在每个按钮上设置 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);
            }

        }));

关于c# - 视觉状态和自定义依赖属性 (MVVM),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19549478/

相关文章:

wpf - 让 ListBox 随窗口调整大小,但不随内容调整大小

c# - 列表框.SelectedItem

c# - WPF ListBoxItem IsMouseOver

C#:用于解码 Quoted-Printable 编码的类?

c# - 从 C# 访问 Firefox

c# wpf 数据绑定(bind)没有发生。

wpf - VsBrush 在 WPF ResourceDictionary 中不起作用

c# - 如何根据条件创建 LINQ to SQL 分组?

c# - WPF层事件分离

c# - 如何在 xaml 中声明 ObservableCollection 命名空间