如何让我的 WPF 自定义形状类在设计器中呈现? [英] How do I get my WPF Custom shape class to render in desiger?

查看:26
本文介绍了如何让我的 WPF 自定义形状类在设计器中呈现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经坚持了几天,在谷歌或几本书上都没有运气.我正在尝试在 WPF 中为 UI 设计创建自定义形状.运行应用程序时,我可以让形状在应用程序窗口中呈现得很好,但它不会在设计器中呈现.

I've been stuck on this for a few days and no luck on Google or a few books. I'm trying to create a custom shape for a UI design in WPF. I can get the shape to render just fine in the application window when running the application, but it doesn't render in the designer.

我已经将测试用例简化为我能想到的最简单的,但没有运气.解决方案是一个简单的主窗口 WPF 应用程序,然后是一个带有自定义形状类的 C# 库.应用程序有一个对 C# 库的项目引用,自定义形状在工具箱中显示得很好.

I've stripped a test case down to the simplest I can come up with, but no luck. The solution is a simple main window WPF application and then a C# library with the custom shape class. Application has a project reference to the C# library and the custom shape shows up just fine in the toolbox.

下图显示了我的形状(左侧)在标准 WPF 椭圆(右侧)旁边的样子.

The pictures below show what my shape (on the left) looks like next to a standard WPF ellipse (on the right).

感谢您提供的任何指导.

Thank you for any direction you can give.

这是我运行应用程序时的样子以及它在设计器中的样子.

This is what it looks like when I run the application and what it should look like in designer.

然而,这是我实际得到的(只是一个蓝色方块):

However this is what I actually get (just a blue square):

MainWindow.xaml:

MainWindow.xaml:

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d3="http://research.microsoft.com/DynamicDataDisplay/1.0"
        xmlns:local="clr-namespace:chenmoH"
        xmlns:WpfCustomControlLibrary1="clr-namespace:WpfCustomControlLibrary1;assembly=WpfCustomControlLibrary1" x:Class="chenmoH.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="800" Width="1200" FontFamily="/chenmoH;component/#Swiss911 UCm BT" WindowStartupLocation="CenterScreen" WindowStyle="None" FontSize="36" Loaded="Window_Loaded" Background="Black" Foreground="White">
    <Grid>
        <WpfCustomControlLibrary1:TestShape Fill="#FF2020DE" HorizontalAlignment="Left" Height="100" Margin="319,387,0,0" Stroke="#FFDE1E1E" VerticalAlignment="Top" Width="100" Radius="50" StrokeThickness="5"/>
        <Ellipse Fill="#FF2020DE" HorizontalAlignment="Left" Height="100" Margin="507,387,0,0" Stroke="#FFDE1E1E" StrokeThickness="5" VerticalAlignment="Top" Width="100"/>
    </Grid>
</Window>

和 TestShape.cs

And the TestShape.cs

namespace WpfCustomControlLibrary1
{
   public sealed class TestShape: Shape
   {
        public TestShape() { }
        public Double Radius
        {
            get { return (Double)this.GetValue(RadiusProperty); }
            set { this.SetValue(RadiusProperty, value); }
        }
        public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register(
      "Radius", typeof(Double), typeof(TestShape), new PropertyMetadata(0.0));

        protected override Geometry DefiningGeometry
        {
            get
            {
                return new EllipseGeometry(new Point(0, 0), Radius, Radius);
            }
        }
    }
}

推荐答案

我看起来很有希望从 Shape 派生出来.不幸的是,它有一些丑陋的缺点:形状不处理调整大小事件,您不能告诉 Shape 调整大小(该方法是私有的),因此它要求一个新的几何图形.我发现的唯一方法是忽略 Shape 并构建自己的控件,这没什么大不了的.在这里.

I looks very promissing to derive from Shape. Unfortunately that has some ugly drawbacks: The shape does not handle resize events and you cannot tell Shape about a resize (that method is private) so that it asks for a new geometry. The only way I found is to ignore Shape and build your own control which isn't a big deal. Here it is.

class TestShape : FrameworkElement
{
    public double Radius
    {
        get { return (double)GetValue (RadiusProperty); }
        set { SetValue (RadiusProperty, value); }
    }

    public static readonly DependencyProperty RadiusProperty =
        DependencyProperty.Register ("Radius", typeof (double), typeof (TestShape), new FrameworkPropertyMetadata (10.0, FrameworkPropertyMetadataOptions.AffectsRender));

    public Brush Fill
    {
        get
        {
            return (Brush)GetValue (FillProperty);
        }
        set
        {
            SetValue (FillProperty, value);
        }
    }

    public static readonly DependencyProperty FillProperty =
        DependencyProperty.Register ("Fill", typeof (Brush), typeof (TestShape), new FrameworkPropertyMetadata (Brushes.AliceBlue, FrameworkPropertyMetadataOptions.AffectsRender));

    public Brush Stroke
    {
        get { return (Brush)GetValue (StrokeProperty); }
        set { SetValue (StrokeProperty, value); }
    }

    public static readonly DependencyProperty StrokeProperty =
        DependencyProperty.Register ("Stroke", typeof (Brush), typeof (TestShape), new FrameworkPropertyMetadata (Brushes.Beige, FrameworkPropertyMetadataOptions.AffectsRender));

    public double StrokeThickness
    {
        get { return (double)GetValue (StrokeThicknessProperty); }
        set { SetValue (StrokeThicknessProperty, value); }
    }

    public static readonly DependencyProperty StrokeThicknessProperty =
        DependencyProperty.Register ("StrokeThickness", typeof (double), typeof (TestShape), new FrameworkPropertyMetadata (1.0, FrameworkPropertyMetadataOptions.AffectsRender));

    protected override void OnRender (DrawingContext drawingContext)
    {
        Point center = new Point (RenderSize.Width / 2, RenderSize.Height / 2);

        var pen = new Pen (Stroke, StrokeThickness);

        drawingContext.DrawEllipse(Fill, pen, center, RenderSize.Width / 2 - StrokeThickness / 2, RenderSize.Height / 2 - StrokeThickness / 2);
    }
}

您可以使用 DrawingContext 的任何方法来绘制形状,而不是 DrawEllipse.

Instead of DrawEllipse you can use any method of the DrawingContext to draw you shape.

这篇关于如何让我的 WPF 自定义形状类在设计器中呈现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆