2016-10-05 2 views

답변

1
  1. 생성자에서 일부 기본값을 설정하십시오.

  2. 기본값은 이며 MouseEnter 이벤트에서 움직입니다.

  3. 일반 및 MouseEnter 시나리오의 경우 VisualStates을 생성하십시오.

  4. MouseEnterMouseLeave 이벤트 핸들러에 VisualStateManager.GoToElementState()를 사용하여 요소의 VisualState을 변경

    .

사용자 지정을 위해 DP를 사용하여 다양한 속성을 노출 할 수 있습니다.

NewShape.cs

using System.Windows.Shapes; 
using System.Windows.Media; 
using System.Windows.Media.Animation; 
using System.Windows; 
using System.Windows.Media.Effects; 

namespace WpfStackOverflow.NewShape 
{ 
    public class CNewShape : Shape 
    { 
     public CNewShape() 
     { 
      // setting the defaults 
      this.Width = 40; 
      this.Height = 40; 
      this.Stroke = new SolidColorBrush() { Color = Colors.Red }; 
      this.StrokeThickness = 5; 
      this.Effect = new DropShadowEffect() { 

       Color = Colors.Transparent, 
       BlurRadius = 1, 
       Direction = -150, 
       ShadowDepth = 1    
      }; 

      // constructing the VisualStates 
      _constructVisualStates(); 

      // event handlers 
      this.MouseEnter += CNewShape_MouseEnter; 
      this.MouseLeave += CNewShape_MouseLeave; 
     } 

     #region EventHandlers 
     void CNewShape_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e) 
     { 
      VisualStateManager.GoToElementState(this, "VSNormal", false); 
     } 

     void CNewShape_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e) 
     { 
      VisualStateManager.GoToElementState(this, "VSMouseEnter", false); 
     } 
     #endregion 

     #region Overrides 

     // This needs to be implemented as it is abstract in base class 
     GeometryGroup geo = new GeometryGroup(); 
     protected override Geometry DefiningGeometry 
     { 
      get { return geo; } 
     } 

     protected override void OnRender(System.Windows.Media.DrawingContext drawingContext) 
     { 
      Pen pen = new Pen(this.Stroke, StrokeThickness); 
      drawingContext.DrawEllipse(Brushes.Transparent, pen, new Point(Width/2, Height/2), 40, 40); 

      drawingContext.DrawEllipse(Stroke, null, new Point(Width/2, Height/2), 30, 30); 
      base.OnRender(drawingContext); 
     } 
     #endregion 

     #region Helpers 

     private void _constructVisualStates() 
     {   
      VisualStateGroup vsg1 = new VisualStateGroup(); 

      #region VSNormal (Normal Visual State) 
       VisualState stateVSNormal = new VisualState() { Name = "VSNormal" }; 

       Storyboard sbVSNormal = new Storyboard(); 
        ObjectAnimationUsingKeyFrames oa = new ObjectAnimationUsingKeyFrames(); 
        Storyboard.SetTargetProperty(oa, new PropertyPath("Effect")); 
        DiscreteObjectKeyFrame dokf = new DiscreteObjectKeyFrame(null); 
        oa.KeyFrames.Add(dokf); 
        sbVSNormal.Children.Add(oa); 

       stateVSNormal.Storyboard = sbVSNormal; 
       vsg1.States.Add(stateVSNormal); 
      #endregion      

      #region VSMouseEnter (MouseEnter Visual State) 
       VisualState stateVSMouseEnter = new VisualState() { Name = "VSMouseEnter" }; 

       Storyboard sbVSMouseEnter = new Storyboard(); 

        ColorAnimation caStrokeColor = new ColorAnimation(); 
        caStrokeColor.To = (Color)ColorConverter.ConvertFromString("#FF24BCDE"); 
        Storyboard.SetTargetProperty(caStrokeColor, new PropertyPath("(Shape.Stroke).(SolidColorBrush.Color)")); 
        sbVSMouseEnter.Children.Add(caStrokeColor); 

        ColorAnimation caEffectColor = new ColorAnimation(); 
        caEffectColor.To = (Color)ColorConverter.ConvertFromString("#FFA4E1F3"); 
        Storyboard.SetTargetProperty(caEffectColor, new PropertyPath("(Shape.Effect).(Color)")); 
        sbVSMouseEnter.Children.Add(caEffectColor); 

        DoubleAnimation daBlurRadius = new DoubleAnimation(); 
        daBlurRadius.To = 10; 
        Storyboard.SetTargetProperty(daBlurRadius, new PropertyPath("(Shape.Effect).(BlurRadius)")); 
        sbVSMouseEnter.Children.Add(daBlurRadius); 

        DoubleAnimation daDirection = new DoubleAnimation(); 
        daDirection.To = -190; 
        Storyboard.SetTargetProperty(daDirection, new PropertyPath("(Shape.Effect).(Direction)")); 
        sbVSMouseEnter.Children.Add(daDirection);    

       stateVSMouseEnter.Storyboard = sbVSMouseEnter; 
       vsg1.States.Add(stateVSMouseEnter); 
      #endregion 

      VisualStateManager.GetVisualStateGroups(this).Add(vsg1); 
     } 

     #endregion 
    } 
} 

사용

<local:CNewShape Canvas.Left="70" Canvas.Top="52" Stroke="#FF374095" StrokeThickness="10" Width="100" Height="100" /> 

이미지의 16,

출력

품질이 좋지 않습니다. 화면에서 실제 출력이 좋아 보인다.

Animated Button

1

트리거가 Highlighted 상태로 들어가면 트리거가 Effect 속성으로 설정됩니다. 당신이 OnRender에 아무것도 할 필요가 없습니다 의미

public static readonly DependencyProperty ShowShadowProperty = 
     DependencyProperty.Register ("ShowShadow", typeof (bool), typeof (TestShape), new PropertyMetadata (false, ShowShadowChanged)); 

    public bool ShowShadow 
    { 
     get { return (bool)GetValue (ShowShadowProperty); } 
     set { SetValue (ShowShadowProperty, value); } 
    } 

    private static void ShowShadowChanged (DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     ((TestShape)d).OnShowShadow(); 
    } 

    private void OnShowShadow() 
    { 
     if (ShowShadow) 
     { 
      Effect = new DropShadowEffect { Direction = 0, ShadowDepth = 20, BlurRadius = 33, Opacity = 1, Color = Colors.Black}; 
     } 
     else 
     { 
      Effect = null; 
     } 
    } 

: 내 테스트를 위해 "트리거"속성입니다.

관련 문제