c# - 从代码隐藏定义 VisualStates

标签 c# wpf visualstatemanager

是否可以在CodeBehind中定义(而不是切换)VisualStates?

我正在创建一个装饰器,它在 OnRender 中绘制一些矩形。我想做的是通过其属性 IsMouseOver 更改这些矩形的不透明度(例如从 0.3 到 0.8)。

在任何具有可视化树的控件中,我都会添加一些 VisualStates 并使用 DataStateBehavior 切换它们。我该如何使用装饰器来做到这一点?

最佳答案

这是完全可能的。

如果有人感兴趣,我是这样做的:

public class MyAdorner: Adorner
{
    ctor (...):base(...)
    {
        ...

        var storyboard = new Storyboard();
        var doubleAnimation = new DoubleAnimation(0.2,new Duration(TimeSpan.Zero));
        Storyboard.SetTarget(doubleAnimation,this);
        Storyboard.SetTargetProperty(doubleAnimation,new PropertyPath(RectOpacityProperty));
        storyboard.Children.Add(doubleAnimation);

        var storyboard2 = new Storyboard();
        var doubleAnimation2 = new DoubleAnimation(0.5, new Duration(TimeSpan.Zero));
        Storyboard.SetTarget(doubleAnimation2, this);
        Storyboard.SetTargetProperty(doubleAnimation2, new PropertyPath(RectOpacityProperty));
        storyboard2.Children.Add(doubleAnimation2);

        var stateGroup = new VisualStateGroup { Name = "MouseOverState" };
        stateGroup.States.Add(new VisualState { Name = "MouseOut", Storyboard = storyboard });
        stateGroup.States.Add(new VisualState { Name = "MouseOver", Storyboard = storyboard2});

        var sgs = VisualStateManager.GetVisualStateGroups(this);
        sgs.Add(stateGroup);

        var dsb = new DataStateBehavior
            {
                Value = true,
                FalseState = "MouseOut",
                TrueState = "MouseOver"
            };
        BindingOperations.SetBinding(dsb, DataStateBehavior.BindingProperty, new Binding {Source = this, Path = new PropertyPath(IsMouseOverProperty)});
        dsb.Attach(this);

    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        drawingContext.DrawRectangle(_mouseOverBrush, _pen, _rects[i]);     //mouseoverbrush is a Solidcolorbrush       
    }

    public double RectOpacity
    {
        get { return (double)GetValue(RectOpacityProperty); }
        set { SetValue(RectOpacityProperty, value); }
    }

    public static readonly DependencyProperty RectOpacityProperty =
        DependencyProperty.Register("RectOpacity", typeof(double), typeof(XmlNodeWrapperAdorner), new FrameworkPropertyMetadata(0.0,FrameworkPropertyMetadataOptions.AffectsRender,(o, args) =>
            {
                var adorner = o as MyAdorner;
                adorner._mouseOverBrush.Color = Color.FromArgb((byte)((double)args.NewValue * 0xFF), 0xFF, 0xBE, 0x00);
            }));

}

实际上非常简单。

这里的要点是:

  • 您无法设置 VisualStateGroups 附加属性。您必须获取集合,然后添加您自己的组

  • 你不能做new DataStateBehavior{Binding = new Binding(...){...}}因为这将分配而不是绑定(bind)某个值到属性。如Behvior<T>不源自FrameworkElement你也不能使用SetBinding但必须使用BindingOperations类。

  • 为了在属性更改时自动重新渲染,请记住设置 FrameworkPropertyMetadataOptions.AffectsRender

关于c# - 从代码隐藏定义 VisualStates,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5529507/

上一篇:c# 时区问题

下一篇:c# - linq 语法选项

相关文章:

c# - Silverlight:来自一个用户控件的事件能否在不同的用户控件和/或包含控件上开始动画

c# - Forms Authentication 添加附加信息以及 ReturnUrl

c# - Funq 支持 ResolveAll 吗?

c# - 在与 WPF 中的子元素不同的父元素上设置不透明度

WPF Popup事件处理-打开Popup时如何触发

c# - 如何验证 PasswordBox WPF

c# - 如何在 Silverlight 4 中等待状态改变转换完成?

c# - 更快的深度克隆

c# - 在使用 C# 获取表单中的所有文本框名称时使用什么函数?

xaml - 在 VisualStateManager (WinRT XAML) 中更改 ItemTemplate 中控件的属性