【问题标题】:Implement mouse interaction on custom control based on FrameworkElement基于FrameworkElement在自定义控件上实现鼠标交互
【发布时间】:2018-01-13 08:45:16
【问题描述】:

这只是学习的例子。

我想创建具有完全不同外观的自定义控件。因此,根据https://docs.microsoft.com/en-us/dotnet/framework/wpf/controls/control-authoring-overview,我派生自FrameworkElement 并覆盖OnRender 方法,如果需要,还可以覆盖OverriderMesureArrangeOverride

现在我想实现鼠标交互,例如:在悬停时将颜色从红色变为蓝色。我该怎么做?

public class Box : FrameworkElement
{
    private static Color defaultColor = Colors.Red;
    public static DependencyProperty ColorProperty = DependencyProperty.Register("Color", typeof(SolidColorBrush), typeof(Box),
        new FrameworkPropertyMetadata(new SolidColorBrush(defaultColor), FrameworkPropertyMetadataOptions.AffectsRender));

    public SolidColorBrush Color
    {
        get { return (SolidColorBrush)GetValue(ColorProperty); }
        set { SetValue(ColorProperty, value); }
    }

    static Box()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(Box), new FrameworkPropertyMetadata(typeof(Box)));
    }

    protected override void OnRender(DrawingContext drawingContext)
    {
        // It's just example, I know shape is wayyy too simple to involve custom render.
        drawingContext.DrawRectangle(Color, null, new Rect(0, 0, ActualWidth, ActualWidth));
    }

    protected override void OnMouseEnter(MouseEventArgs e)
    {
        Color = new SolidColorBrush(Colors.Blue); // Set to color
    }

    protected override void OnMouseLeave(MouseEventArgs e)
    {
        Color = new SolidColorBrush(defaultColor); // Back to default
    }

    protected override Size MeasureOverride(Size constraint)
    {
       ...
    }

    protected override Size ArrangeOverride(Size finalSize)
    {
       ...
    }
}

到目前为止,我推断:
通常,如果我从 Control 派生,我会为此使用 VSM。不幸的是,VSM 直到 ControlTemplate 层次结构树才可用,因此具有 Template 属性的控件。因此,如果我决定自己绘制控件,我需要用于此路由事件,在此特定示例中 OnMouseEnter(MouseEventArgs)OnMouseLeave(MouseEventArgs) 和一些依赖属性,如上面的代码。

这是正确的方法吗?请记住这是为了学习目的,所以FrameworkElement作为基础是强制性的。

我可以看到一些缺点,因为如果我们想要控制 onHover 颜色(在上面的代码中被硬编码为蓝色),我需要处理后面的代码,或者为此创建另一个依赖属性。

【问题讨论】:

  • 请注意,Brush 类型的属性不应称为“颜色”。像往常一样,最好将其称为前景或背景。另请注意,new SolidColorBrush(Colors.Blue) 是多余的。有 Brushes 类,它有 Brushes.Blue
  • @Clemens 是的,你可能是对的,名字不准确。

标签: wpf controls


【解决方案1】:

不幸的是,VSM 直到 ControlTemplate 层次结构树才可用,因此具有 Template 属性的控件。

这不是真的。

您可以正常使用 VSM,只需进行一些小改动。阅读:https://msdn.microsoft.com/en-us/library/system.windows.visualstatemanager(v=vs.110).aspx#Examples。仔细查看示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 2011-12-19
    • 1970-01-01
    • 2012-07-20
    相关资源
    最近更新 更多