Определите VisualStates из Codebehind - PullRequest
2 голосов
/ 03 апреля 2011

возможно ли определить (не переключать) VisualStates в CodeBehind?

Я создаю Adorner, который рисует некоторые прямоугольники в OnRender.Я хотел бы изменить непрозрачность этих прямоугольников по свойству IsMouseOver (скажем, от 0,3 до 0,8).

В любом элементе управления с визуальным деревом я бы добавил несколько VisualStates и переключилсяте с DataStateBehavior.Как мне это сделать с Adorner?

Ответы [ 3 ]

4 голосов
/ 04 апреля 2011

это вполне возможно.

если кому-то интересно, вот как я это сделал:

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.

0 голосов
/ 03 апреля 2011

Поскольку вы уже создаете собственный рекламный элемент с вашим собственным поведением, я бы предложил переопределить метод MouseOver для рекламного элемента и изменить там непрозрачность ваших прямоугольников ...

другим способомпрослушивать собственное событие PropertyChanged и отслеживать изменения в IsMouseOver, или, возможно, отслеживать событие MouseMove ...

0 голосов
/ 03 апреля 2011

Если бы вы могли добавлять состояния в коде, таким инструментам, как Blend, пришлось бы запускать весь код во всех возможных конфигурациях, чтобы выяснить, какие состояния присутствуют / возможны.

Итак, нет, вы не можете сделатьэто в коде.Это возможно только с использованием атрибутов.

РЕДАКТИРОВАТЬ

Я исправлен, но упомянутая проблема все еще остается.Эта техника бесполезна для дизайнеров.

...