已回答 在PictureBox上填充复杂的外部形状

莱顿

成员
已加入
2020年7月24日
留言内容
9
编程经验
10+
嗨,我是C#的新手,我想重新编写一个我最近在VBA中开发的应用程序。
我在PowerPoint中从外部绘制了一些复杂的形状,并另存为.png和/或.bmp图片。我已将其中一个手动加载到pictureBox1上。现在,我想通过一个控件来填充纯色,比如说一个滑块,在某个范围内每秒可应用5-10种RGB颜色(在垂直滑块的整个范围内有250种以上的颜色)。
我怎样才能做到这一点?我在网络上发现的大多数“填充颜色”示例都涉及绘制矩形/椭圆形然后进行填充。由于我已经在窗体上加载了形状,如何引入它然后更改颜色?我的图片包括两部分:外部块-用作背景的矩形和需要绘制/填充的不规则内部形状。为了赋予Paint程序的Fill效果,我应该首先在内部形状中定义一个像素吗?
谢谢..
 

羊皮

知名会员
已加入
2018年9月5日
留言内容
1,982
编程经验
10+
您好,欢迎来到论坛。

那是什么问题呢?在您的帖子中,我看不到任何上面的代码来显示您的尝试。

由于我已经在窗体上加载了形状,如何引入它然后更改颜色?
由于您是从VBA进入C#的。我认为您需要在设计此新应用程序时指定要计划的项目类型?如果您选择Winforms,我想说您是在浪费时间,因为Winforms是停产和过时的,其次,我建议在WPF中进行此操作。 WPF提供的形状可能会更好,这取决于您要尝试执行的操作。 WPF还更快,并且设计用于处理形状和图形。 。 。

图片框的目的是什么?
 
Last edited:

莱顿

成员
已加入
2020年7月24日
留言内容
9
编程经验
10+
我在VBA中拥有的应用程序主要由一个窗体和一个位于中心的图像控件组成。然后有两个滑块,水平滑块可更改形状(从1到7),而垂直滑块可根据温度颜色方案更改形状的颜色。它们共同形成用户决定的正确图片。换句话说,正确的图片是充满所需临时颜色的正确形状。图片固定后,用户可以从列表框或单选按钮控件中选择表单上的其他参数,最后单击“计算”按钮,您将获得计算得出的设备容量。它是一种工程计算器。我无法附加任何代码,因为我所拥有的只是一个不完整的表格,但是还没有代码。我尝试过的所有操作都会产生错误。.也许VBA Excel表单的屏幕视图使您可以更好地可视化我所遇到的问题,我将其附加在一起。
 

附件

  • VBA表格转换为C#.pdf
    361.5 KB · Views: 7

羊皮

知名会员
已加入
2018年9月5日
留言内容
1,982
编程经验
10+
我有点怀疑。好的,不要使用Winforms,因为它既旧又过时并且停产。

WPF仅凭速度便胜过它,它是专为包括绘图和处理形状的项目而设计的。

在WPF中,您可以使用矩形的fill属性。在Xaml中,您可以执行以下操作:

C#:
<Rectangle Width="650" Height="320">
    <Rectangle.Fill>
        <SolidColorBrush Color="Blue" />
    </Rectangle.Fill>
</Rectangle>
或后面的代码:
C#:
Rectangle_Obkect.Fill = new SolidColorBrush(Color.FromRgb(0, 130, 222));

这里的更多信息: Shape.Fill属性(System.Windows.Shapes)

对于绘制形状等,您可以看到: 形状和基本工程图概述-WPF

因此,总的来说,我认为WPF是goto项目。希望这些链接对您有所帮助。如果您遇到困难,则需要回发一些实际代码并显示您尝试过的内容。 (y)
 

莱顿

成员
已加入
2020年7月24日
留言内容
9
编程经验
10+
太好了。非常感谢。我会按照你的建议。希望我能解决这个关键点,其余的事情会更简单!

Mod编辑:无需引用全引号。选择要报价的部分。否则,它将占用移动用户不必要的空间。
 
由主持人最后编辑:

羊皮

知名会员
已加入
2018年9月5日
留言内容
1,982
编程经验
10+
好吧,如果您遇到困难,您知道我们在哪里。

如果可以的话,总是很乐意为您提供帮助。 ;)
 

莱顿

成员
已加入
2020年7月24日
留言内容
9
编程经验
10+
尽管您建议我应该使用WPF,但不幸的是,我到那儿都没有。.至少,我可以使用水平滑块更改7张图片。我的图片作为Part1.png到Part7.png加载到资源中,我在hor滑块的滚动事件处理程序调用的ActivePicture()方法中进行选择和检索,如下所示:

C#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp5
{
    public partial class Form1 : Form
    {        
        public Form1()
        {
            InitializeComponent();
            
            label1.Text = "Part" + (hScrollBar1.Value / 10);
            label2.Text = "" + (hScrollBar1.Value / 10);

            ActivePicture();

        }
        private void ActivePicture()
        {
            int caseSwitch = (hScrollBar1.Value / 10);

            switch (caseSwitch)
            {
                case 1:
                    pictureBox1.Image = Properties.Resources.Part1;
                    break;
                case 2:
                    pictureBox1.Image = Properties.Resources.Part2;
                    break;
                case 3:
                    pictureBox1.Image = Properties.Resources.Part3;
                    break;
                case 4:
                    pictureBox1.Image = Properties.Resources.Part4;
                    break;
                case 5:
                    pictureBox1.Image = Properties.Resources.Part5;
                    break;
                case 6:
                    pictureBox1.Image = Properties.Resources.Part6;
                    break;
                default:
                    pictureBox1.Image = Properties.Resources.Part7;
                    break;
            }
        }


        private void hScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            ActivePicture();
            
            label1.Text = "Part" + (hScrollBar1.Value / 10);
            label2.Text  = "" + (hScrollBar1.Value / 10);
        }
        private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            ActivePicture();

            //FillPathEllipse();
        }
        public void FillPathEllipse(PaintEventArgs e)
        {
            // Create solid brush.
            SolidBrush redBrush = new SolidBrush(Color.Red);

            // Create graphics path object and add ellipse.
            GraphicsPath graphPath = new GraphicsPath();
            graphPath.AddEllipse(0, 0, 200, 100);

            // Fill graphics path to screen.
            e.Graphics.FillPath(redBrush, graphPath);
        }
    }
}

Q1)是否有更好的方法来替换我使用caseSwitch的方法ActivePicture()?我尝试了一系列图像,但均未成功
Q2)这是更重要的部分。现在,我希望vSliderBar1沿滚动向上移动几次更改hSliderBar1选择的部分的颜色(250+ RGB颜色)。我已经通过您建议的链接尝试了几种方法,但不幸的是我失败了。我希望在“图片”的中心填充一个小椭圆,但它也会引发错误,因此我无法正常工作。

如果在WinForms中获得成功的结果(Q2),我的下一个挑战将是在WPF中尝试相同的结果。.谢谢
 
由主持人最后编辑:

跳伞者

工作人员
已加入
2019年4月6日
留言内容
2,612
地点
弗吉尼亚州切萨皮克
编程经验
10+
如果您不告诉我们您遇到的错误,我们将无法在第二季度为您提供帮助。这些是什么?

Can we assuming that you have attached FillPathEllipse() to the Paint event of the picture box?

至于Q1,当您拥有看起来像代码的代码时,转到数据结构将是数组或字典。您能告诉我们您使用数组的尝试吗?
 

莱顿

成员
已加入
2020年7月24日
留言内容
9
编程经验
10+
参考Q2 ..
我已经将FillPathEllipse()附加到垂直Slider的Scroll事件和我得到的错误:

C#:
        private void vScrollBar1_Scroll(object sender, ScrollEventArgs e)
        {
            ActivePicture();
            FillPathEllipse();  // This is where the error throws as "there is no argument given that corresponds to

            // the required formal parameter  'e' of 'Form1.FillPathEllipse(PaintEventArgs)'

        }
        public void FillPathEllipse(PaintEventArgs e)
        {
            // Create solid brush.
            SolidBrush redBrush = new SolidBrush(Color.Red);
            // Create graphics path object and add ellipse.
            GraphicsPath graphPath = new GraphicsPath();
            graphPath.AddEllipse(0, 0, 200, 100);

            // Fill graphics path to screen.

            e.Graphics.FillPath(redBrush, graphPath);
        }
 
由主持人最后编辑:

莱顿

成员
已加入
2020年7月24日
留言内容
9
编程经验
10+
参考Q1 ..

我已经尝试过如下所示的Picture数组,它是从本论坛的另一个类似案例中获得的:

C#:
        public Form1()
        {
            InitializeComponent();
            
            label1.Text = "Part" + (hScrollBar1.Value / 10);
            label2.Text = "" + (hScrollBar1.Value / 10);

            //ActivePicture();

            pictureBox1.Image = getImages(0);  // error message: No overload for method 'getImages' takes 1 arguments

        }

        private Image[] getImages()
        {
            Image[] images = new Image[7];

            images[0] = Properties.Resources.Part1;
            images[1] = Properties.Resources.Part2;
            images[2] = Properties.Resources.Part3;
            images[3] = Properties.Resources.Part4;
            images[4] = Properties.Resources.Part5;
            images[5] = Properties.Resources.Part6;
            images[6] = Properties.Resources.Part7;

            return images;
        }
 

莱顿

成员
已加入
2020年7月24日
留言内容
9
编程经验
10+
第9行告诉您如果您阅读自己的代码,这是什么。
谢谢!但是,如果您不想在回答新来者时更加明确,请不要打扰。
无需重复错误消息已经说明的内容。如果我能和他们一起做的话,我不会一开始就在这里!
 

羊皮

知名会员
已加入
2018年9月5日
留言内容
1,982
编程经验
10+
谢谢!但是,如果您不想在回答新来者时更加明确,请不要打扰。
放松你的腿,不要粗鲁。您正在获得帮助。我不知道您不想被人喂也是我的错。

似乎很明显。您的方法有一个参数,但您没有提供它。什么不明白?

也许您会发现我链接的文档比我之前提到的明显观点更有用。
 

羊皮

知名会员
已加入
2018年9月5日
留言内容
1,982
编程经验
10+
我通常不协助那些无礼的人。但是,我会例外处理,让您感到沮丧。同时,需要重点注意的是,这是一个旨在培训疑难解答程序的帮助论坛。我试图让您注意自己的代码。让我换一种说法:用Graphics对象绘制图形,然后通过PaintEventArgs传递该图形。
 

跳伞者

工作人员
已加入
2019年4月6日
留言内容
2,612
地点
弗吉尼亚州切萨皮克
编程经验
10+
Part of the issue is that the OP didn't write that code for FillPathEllipse(). Notice that naming convention doesn't match the rest of his code. Looks like he just copied and pasted the sample code from the MSDN documentation for FillPath()
 

羊皮

知名会员
已加入
2018年9月5日
留言内容
1,982
编程经验
10+
因此,OP在链接这些文档之前一直在阅读文档,但是尽管由我自己记录和解释了该问题,但仍然不理解该问题。呃,好吧
 
最佳 底部