首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从代码背后定义VisualStates

从代码背后定义VisualStates
EN

Stack Overflow用户
提问于 2011-04-03 12:13:32
回答 2查看 1.8K关注 0票数 2

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

我正在创建一个Adorner,它在OnRender中绘制一些矩形。我想要做的是通过属性IsMouseOver来改变这些矩形的不透明度(比如从0.3到0.8)。

在任何带有可视树的控件中,我都会添加一些VisualStates并使用DataStateBehavior切换那些控件。我怎么和Adorner一起做这件事?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-04-03 21:07:55

这是完全可能的。

如果有人对此感兴趣,那就是我是如何做到的:

代码语言:javascript
运行
复制
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(...){...}},因为这将为属性分配而不是绑定一些值。由于Behvior<T>不是从FrameworkElement派生的,所以您也不能使用SetBinding,而是必须使用BindingOperations类.
  • 来在属性更改时自动重命名,请记住设置FrameworkElement
票数 4
EN

Stack Overflow用户

发布于 2011-04-03 16:45:49

既然您已经用自己的行为创建了一个自定义装饰器,我建议您重写装饰器的MouseOver方法,并在那里更改矩形的不透明度。

另一种方法是监听您自己的PropertyChanged事件并监视IsMouseOver中的更改,或者监视MouseMove事件.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5529507

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档