是否存在类型“ChartColorPalette”的现有 PropertyGrid UITypeEditor?

发布于 2024-09-09 03:06:58 字数 316 浏览 1 评论 0原文

我正在尝试编写一个简单的属性网格以允许用户修改图表的颜色。默认情况下,图表有一个“Palette”属性,其枚举类型为“ChartColorPalette”。如果我的属性网格下的对象也具有相同类型的“Palette”属性,我将获得可能值的下拉列表。然而,我没有得到的是值名称左侧的小条纹图像。

现在,我可以编写一个 UITypeEditor 派生类,并让“PaintValue”绘制一些资源位图,这些资源位图是我使用“Paint”或类似方法从屏幕上挑选出来的,但这看起来相当乏味。

有谁知道是否已经有一个用于“ChartColorPalette”枚举的类型编辑器,我可以用它来获取小位图?

I'm trying to write a simple property grid to allow the users to modify the colours of a Chart. By default, a Chart has a "Palette" property, which is of the enumeration type "ChartColorPalette". If the object which underlies my property grid also has a "Palette" property of the same type, I get the drop-down list of possible values. What I don't get however, is the little stripey images to the left of the value names.

Now, I can write a UITypeEditor derived class and have the "PaintValue" draw little resource bitmaps which I have culled from the screen using "Paint" or somesuch, but this seems rather tedious.

Does anyone know if there is already a type editor for the "ChartColorPalette" enumeration which I can use to get the little bitmaps ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

奢望 2024-09-16 03:06:58

事实上,编写 UITypeEditor 并不那么棘手,也不需要那么多代码。
首先,我创建了一个如下所示的类型编辑器:

private class ChartColorPaletteEditor : UITypeEditor
{
    public override bool GetPaintValueSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override void PaintValue(PaintValueEventArgs e)
    {
        String paletteName = e.Value.ToString();
        String baseName = this.GetType().Namespace + ".MyChart";
        ResourceManager mgr = new ResourceManager(baseName, this.GetType().Assembly);
        Bitmap bmp = mgr.GetObject(paletteName) as Bitmap;
        if (bmp != null)
        {
            e.Graphics.DrawImage(bmp, e.Bounds);
            bmp.Dispose();
        }
    }
}

我以通常的方式将其附加到我的控件属性:

[DefaultValue(typeof(ChartColorPalette), "BrightPastel")]
[Editor(typeof(ChartColorPaletteEditor), typeof(System.Drawing.Design.UITypeEditor))]
[Category("Appearance")]
[Description("The named palette to use when choosing the colour scheme for the chart series lines.")]
public ChartColorPalette Palette { get; set; }

然后,我为每个小调色板图像添加了一个小的 PNG 资源。我有一个派生控件“MyChart”,它继承自“Chart”,并将图像作为资源添加到其中(确保将“Persistance”属性设置为“Embedded in .resx”,以避免保留 PNG 文件) 。 PNG 文件的名称与 ChartColorPalette 枚举中的名称匹配。

唯一的问题是从哪里获取 20 x 14 的小图像。我最初只是使用 Paint.exe 剔除它们,但不喜欢那样,所以我编写了一些代码来为我生成它们。当我找到图表控件使用的颜色值后,这相当简单。一个微妙之处在于,当调色板中有超过 12 种颜色时,小位图会使用所有其他颜色。该代码如下所示:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Windows.Forms.DataVisualization.Charting;

namespace ConsoleApplication10
{
class Program
{
  static void Main(string[] args)
  {
     Enum.GetValues(typeof(ChartColorPalette)).OfType<ChartColorPalette>().ToList().ForEach(GeneratePNG);
  }

  static void GeneratePNG(ChartColorPalette palette)
  {
     if (palette == ChartColorPalette.None) return;

     Color[] colours = palette.GetColors();

     if (colours.Length >= 12)
     {
        colours = new Color[] { colours[0], colours[2], colours[4], colours[6], colours[8], colours[10] };
     }
     else
     {
        colours = new Color[] { colours[0], colours[1], colours[2], colours[3], colours[4], colours[5] };
     }

     using (Bitmap bmp = new Bitmap(20, 14))
     {
        using (Graphics gr = Graphics.FromImage(bmp))
        {
           using (SolidBrush b1 = new SolidBrush(colours[0]),
                             b2 = new SolidBrush(colours[1]),
                             b3 = new SolidBrush(colours[2]),
                             b4 = new SolidBrush(colours[3]),
                             b5 = new SolidBrush(colours[4]),
                             b6 = new SolidBrush(colours[5]))
           {
              int height = bmp.Height - 2;
              gr.DrawRectangle(Pens.Black, 0, 0, bmp.Width - 1, bmp.Height - 1);
              gr.FillRectangle(b1, new Rectangle(1, 1, 3, height));
              gr.FillRectangle(b2, new Rectangle(4, 1, 3, height));
              gr.FillRectangle(b3, new Rectangle(7, 1, 3, height));
              gr.FillRectangle(b4, new Rectangle(10, 1, 3, height));
              gr.FillRectangle(b5, new Rectangle(13, 1, 3, height));
              gr.FillRectangle(b6, new Rectangle(16, 1, 3, height));
           }
        }

        String path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        path = Path.Combine(path, @"Visual Studio 2010\Projects\DataVisualization.Charting\Palette Bitmaps");

        String filename = palette.ToString() + ".png";
        bmp.Save(Path.Combine(path, filename), ImageFormat.Png);
     }
  }
}

public static class Extensions
{
  public static Color[] GetColors(this ChartColorPalette value)
  {
     switch (value)
     {
        case ChartColorPalette.Berry:
           return GetColors(0x8a2be2, 0xba55d3, 0x4169e1, 0xc71585, 0x0000ff, 0x8a2be2, 0xda70d6, 0x7b68ee, 0xc000c0, 0x0000cd, 0x800080);
        case ChartColorPalette.Bright:
           return GetColors(0x008000, 0x0000ff, 0x800080, 0x00ff00, 0xff00ff, 0x008080, 0xffff00, 0x808080, 0x00ffff, 0x000080, 0x800000, 0xff0000, 0x808000, 0xc0c0c0, 0xff6347, 0xffe4b5);
        case ChartColorPalette.BrightPastel:
           return GetColors(0x418cf0, 0xfcb441, 0xe0400a, 0x056492, 0xbfbfbf, 0x1a3b69, 0xffe382, 0x129cdd, 0xca6b4b, 0x005cdb, 0xf3d288, 0x506381, 0xf1b9a8, 0xe0830a, 0x7893be);
        case ChartColorPalette.Chocolate:
           return GetColors(0xa0522d, 0xd2691e, 0x8b0000, 0xcd853f, 0xa52a2a, 0xf4a460, 0x8b4513, 0xc04000, 0xb22222, 0xb65c3a);
        case ChartColorPalette.EarthTones:
           return GetColors(0xff8000, 0xb8860b, 0xc04000, 0x6b8e23, 0xcd853f, 0xc0c000, 0x228b22, 0xd2691e, 0x808000, 0x20b2aa, 0xf4a460, 0x00c000, 0x8fbc8b, 0xb22222, 0x8b4513, 0xc00000);
        case ChartColorPalette.Excel:
           return GetColors(0x9999ff, 0x993366, 0xffffcc, 0xccffff, 0x660066, 0xff8080, 0x0066cc, 0xccccff, 0x000080, 0xff00ff, 0xffff00, 0x00ffff, 0x800080, 0x800000, 0x008080, 0x0000ff);
        case ChartColorPalette.Fire:
           return GetColors(0xffd700, 0xff0000, 0xff1493, 0xdc143c, 0xff8c00, 0xff00ff, 0xffff00, 0xff4500, 0xc71585, 0xdde221);
        case ChartColorPalette.Grayscale:
           return GetColors(0xc8c8c8, 0xbdbdbd, 0xb2b2b2, 0xa7a7a7, 0x9c9c9c, 0x919191, 0x868686, 0x7b7b7b, 0x707070, 0x656565, 0x5a5a5a, 0x4f4f4f, 0x444444, 0x393939, 0x2e2e2e, 0x232323);
        case ChartColorPalette.Light:
           return GetColors(0xe6e6fa, 0xfff0f5, 0xffdab9, 0xfffacd, 0xffe4e1, 0xf0fff0, 0xf0f8ff, 0xf5f5f5, 0xfaebd7, 0xe0ffff);
        case ChartColorPalette.Pastel:
           return GetColors(0x87ceeb, 0x32cd32, 0xba55d3, 0xf08080, 0x4682b4, 0x9acd32, 0x40e0d0, 0xff69b4, 0xf0e68c, 0xd2b48c, 0x8fbc8b, 0x6495ed, 0xdda0dd, 0x5f9ea0, 0xffdab9, 0xffa07a);
        case ChartColorPalette.SeaGreen:
           return GetColors(0x2e8b57, 0x66cdaa, 0x4682b4, 0x008b8b, 0x5f9ea0, 0x3cb371, 0x48d1cc, 0xb0c4de, 0xffffff, 0x87ceeb);
        case ChartColorPalette.SemiTransparent:
           return GetColors(0xff6969, 0x69ff69, 0x6969ff, 0xffff69, 0x69ffff, 0xff69ff, 0xcdb075, 0xffafaf, 0xafffaf, 0xafafff, 0xffffaf, 0xafffff, 0xffafff, 0xe4d5b5, 0xa4b086, 0x819ec1);
        case ChartColorPalette.None:
        default:
           return GetColors(0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000);
     }
  }

  private static Color[] GetColors(params Int32[] values)
  {
     return values.Select(value => Color.FromArgb(255, Color.FromArgb(value))).ToArray(); // alpha channel of 255 for fully opaque
  }
 }
}

希望这对那里的人有用......

as it happens, writing the UITypeEditor is not that tricky, and not that much code either.
Firstly I created a type editor that looked like this:

private class ChartColorPaletteEditor : UITypeEditor
{
    public override bool GetPaintValueSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override void PaintValue(PaintValueEventArgs e)
    {
        String paletteName = e.Value.ToString();
        String baseName = this.GetType().Namespace + ".MyChart";
        ResourceManager mgr = new ResourceManager(baseName, this.GetType().Assembly);
        Bitmap bmp = mgr.GetObject(paletteName) as Bitmap;
        if (bmp != null)
        {
            e.Graphics.DrawImage(bmp, e.Bounds);
            bmp.Dispose();
        }
    }
}

I attached this to my control property in the usual way:

[DefaultValue(typeof(ChartColorPalette), "BrightPastel")]
[Editor(typeof(ChartColorPaletteEditor), typeof(System.Drawing.Design.UITypeEditor))]
[Category("Appearance")]
[Description("The named palette to use when choosing the colour scheme for the chart series lines.")]
public ChartColorPalette Palette { get; set; }

Then I added a small PNG resource for each of the little palette images. I had a derived control "MyChart" which inherited from "Chart" and I added the images to that as resources (making sure to set the "Persistance" property to "Embedded in .resx" to save having to keep the PNG files about). The names of the PNG files matched the names in the ChartColorPalette enumeration.

The only issue was where to get the little 20 x 14 images from. I originally just culled them using Paint.exe but didn't like that, so I wrote some code to generate them for me. That was fairly simple, once I had found the colour values that are used by the Charting control. One subtlety is that, where there are more than 12 colours in a palette, the little bitmap uses every other colour. That code looked like this:

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Windows.Forms.DataVisualization.Charting;

namespace ConsoleApplication10
{
class Program
{
  static void Main(string[] args)
  {
     Enum.GetValues(typeof(ChartColorPalette)).OfType<ChartColorPalette>().ToList().ForEach(GeneratePNG);
  }

  static void GeneratePNG(ChartColorPalette palette)
  {
     if (palette == ChartColorPalette.None) return;

     Color[] colours = palette.GetColors();

     if (colours.Length >= 12)
     {
        colours = new Color[] { colours[0], colours[2], colours[4], colours[6], colours[8], colours[10] };
     }
     else
     {
        colours = new Color[] { colours[0], colours[1], colours[2], colours[3], colours[4], colours[5] };
     }

     using (Bitmap bmp = new Bitmap(20, 14))
     {
        using (Graphics gr = Graphics.FromImage(bmp))
        {
           using (SolidBrush b1 = new SolidBrush(colours[0]),
                             b2 = new SolidBrush(colours[1]),
                             b3 = new SolidBrush(colours[2]),
                             b4 = new SolidBrush(colours[3]),
                             b5 = new SolidBrush(colours[4]),
                             b6 = new SolidBrush(colours[5]))
           {
              int height = bmp.Height - 2;
              gr.DrawRectangle(Pens.Black, 0, 0, bmp.Width - 1, bmp.Height - 1);
              gr.FillRectangle(b1, new Rectangle(1, 1, 3, height));
              gr.FillRectangle(b2, new Rectangle(4, 1, 3, height));
              gr.FillRectangle(b3, new Rectangle(7, 1, 3, height));
              gr.FillRectangle(b4, new Rectangle(10, 1, 3, height));
              gr.FillRectangle(b5, new Rectangle(13, 1, 3, height));
              gr.FillRectangle(b6, new Rectangle(16, 1, 3, height));
           }
        }

        String path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
        path = Path.Combine(path, @"Visual Studio 2010\Projects\DataVisualization.Charting\Palette Bitmaps");

        String filename = palette.ToString() + ".png";
        bmp.Save(Path.Combine(path, filename), ImageFormat.Png);
     }
  }
}

public static class Extensions
{
  public static Color[] GetColors(this ChartColorPalette value)
  {
     switch (value)
     {
        case ChartColorPalette.Berry:
           return GetColors(0x8a2be2, 0xba55d3, 0x4169e1, 0xc71585, 0x0000ff, 0x8a2be2, 0xda70d6, 0x7b68ee, 0xc000c0, 0x0000cd, 0x800080);
        case ChartColorPalette.Bright:
           return GetColors(0x008000, 0x0000ff, 0x800080, 0x00ff00, 0xff00ff, 0x008080, 0xffff00, 0x808080, 0x00ffff, 0x000080, 0x800000, 0xff0000, 0x808000, 0xc0c0c0, 0xff6347, 0xffe4b5);
        case ChartColorPalette.BrightPastel:
           return GetColors(0x418cf0, 0xfcb441, 0xe0400a, 0x056492, 0xbfbfbf, 0x1a3b69, 0xffe382, 0x129cdd, 0xca6b4b, 0x005cdb, 0xf3d288, 0x506381, 0xf1b9a8, 0xe0830a, 0x7893be);
        case ChartColorPalette.Chocolate:
           return GetColors(0xa0522d, 0xd2691e, 0x8b0000, 0xcd853f, 0xa52a2a, 0xf4a460, 0x8b4513, 0xc04000, 0xb22222, 0xb65c3a);
        case ChartColorPalette.EarthTones:
           return GetColors(0xff8000, 0xb8860b, 0xc04000, 0x6b8e23, 0xcd853f, 0xc0c000, 0x228b22, 0xd2691e, 0x808000, 0x20b2aa, 0xf4a460, 0x00c000, 0x8fbc8b, 0xb22222, 0x8b4513, 0xc00000);
        case ChartColorPalette.Excel:
           return GetColors(0x9999ff, 0x993366, 0xffffcc, 0xccffff, 0x660066, 0xff8080, 0x0066cc, 0xccccff, 0x000080, 0xff00ff, 0xffff00, 0x00ffff, 0x800080, 0x800000, 0x008080, 0x0000ff);
        case ChartColorPalette.Fire:
           return GetColors(0xffd700, 0xff0000, 0xff1493, 0xdc143c, 0xff8c00, 0xff00ff, 0xffff00, 0xff4500, 0xc71585, 0xdde221);
        case ChartColorPalette.Grayscale:
           return GetColors(0xc8c8c8, 0xbdbdbd, 0xb2b2b2, 0xa7a7a7, 0x9c9c9c, 0x919191, 0x868686, 0x7b7b7b, 0x707070, 0x656565, 0x5a5a5a, 0x4f4f4f, 0x444444, 0x393939, 0x2e2e2e, 0x232323);
        case ChartColorPalette.Light:
           return GetColors(0xe6e6fa, 0xfff0f5, 0xffdab9, 0xfffacd, 0xffe4e1, 0xf0fff0, 0xf0f8ff, 0xf5f5f5, 0xfaebd7, 0xe0ffff);
        case ChartColorPalette.Pastel:
           return GetColors(0x87ceeb, 0x32cd32, 0xba55d3, 0xf08080, 0x4682b4, 0x9acd32, 0x40e0d0, 0xff69b4, 0xf0e68c, 0xd2b48c, 0x8fbc8b, 0x6495ed, 0xdda0dd, 0x5f9ea0, 0xffdab9, 0xffa07a);
        case ChartColorPalette.SeaGreen:
           return GetColors(0x2e8b57, 0x66cdaa, 0x4682b4, 0x008b8b, 0x5f9ea0, 0x3cb371, 0x48d1cc, 0xb0c4de, 0xffffff, 0x87ceeb);
        case ChartColorPalette.SemiTransparent:
           return GetColors(0xff6969, 0x69ff69, 0x6969ff, 0xffff69, 0x69ffff, 0xff69ff, 0xcdb075, 0xffafaf, 0xafffaf, 0xafafff, 0xffffaf, 0xafffff, 0xffafff, 0xe4d5b5, 0xa4b086, 0x819ec1);
        case ChartColorPalette.None:
        default:
           return GetColors(0x000000, 0x000000, 0x000000, 0x000000, 0x000000, 0x000000);
     }
  }

  private static Color[] GetColors(params Int32[] values)
  {
     return values.Select(value => Color.FromArgb(255, Color.FromArgb(value))).ToArray(); // alpha channel of 255 for fully opaque
  }
 }
}

Hope this is useful to someone out there...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文