是否可以在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/