我在显示透明背景的透明图像时遇到问题。透明背景采用底层控件的颜色,这很好......问题是底层背景上的一些细节(线条)正在覆盖图像,如下图所示。
这是我正在使用的代码....这是笔记的代码....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Media;
using System.Drawing;
namespace Simpe_Piano_new
{
class MusicNote: PictureBox
{
public SoundPlayer sp = new SoundPlayer();
Timer tmr = new Timer();
public int pitch; //The no. of the music key (e.g. the sound freuency).
public int noteDuration; //Shape of note.
public string noteShape;
public MusicNote(int iPitch, int iNoteDuration)
: base()
{
pitch = iPitch;
noteDuration = iNoteDuration;
Size = new Size(40, 40);
}
public void ShowNote()
{ if (this.noteDuration == 1) noteShape = "Quaver.png";
if (this.noteDuration == 4) noteShape = "Crotchet.png";
if (this.noteDuration == 7) noteShape = "minim.png";
if (this.noteDuration == 10) noteShape = "DotMin.png";
if (this.noteDuration == 12) noteShape = "SemiBreve.png";
this.BackgroundImage = Image.FromFile(noteShape);
this.BackColor = Color.Transparent;
Location = new Point((pitch * 40) - 40, 100);
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
public void PlaySound()
{
sp.SoundLocation = this.pitch + ".wav";
sp.Play();
}
public void StopSound()
{
sp.SoundLocation = this.pitch + ".wav";
sp.Stop();
}
public void Play()
{
sp.SoundLocation = this.pitch + ".wav";
sp.Play();
//Time to play the duration
tmr.Interval = noteDuration;
tmr.Start();
tmr.Tick += new System.EventHandler(ClockTick);
}
void ClockTick(object sender, EventArgs e)
{
sp.Stop();
tmr.Stop();
}
}
}
这是基础控制的代码......音乐人员
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
namespace Simpe_Piano_new
{
public class MusicStaff: Panel
{
Pen myPen;
Graphics g;
public MusicStaff()
{
this.Size = new Size(1000, 150);
this.Location = new Point(0, 0);
this.BackColor = Color.Transparent;
this.Paint += new PaintEventHandler(DrawLines);
}
private void DrawLines(object sender, PaintEventArgs pea)
{
myPen = new Pen(Color.Black, 1);
g = this.CreateGraphics();
for (int i = 1; i < 6; i++)
{
g.DrawLine(myPen, 0, (this.Height / 6) * i, this.Width, (this.Height / 6) * i);
}
}
}
}
我发现C#不能很好地处理透明度...... 任何帮助将不胜感激..
答案 0 :(得分:1)
两个错误。 PictureBox支持透明图像,只要将其BackColor属性设置为Color.Transparent即可。你为MusicStaff做了哪些但没有为MusicNote做过。分层透明不起作用,你不需要MusicStaff透明,只需要图片框。
通过要求Parent将自身绘制到控件中以提供背景像素来模拟这种透明度。这是你的第二个错误,你在DrawLines()方法中使用CreateGraphics()。它直接绘制到屏幕上,而不是控制界面。你必须在这里使用pea.Graphics。
请注意,使用PictureBox获得的增值是非常低的。控件很昂贵,你可以很容易地烧掉数百个来显示一张音乐。你会注意到,涂漆本身会很慢。你可以通过让MusicStaff只是自己绘制笔记来避免这种情况,使用Graphics.DrawImage()来完成工作。透明效果现在也变得更加简单,只是油漆层。这是WPF的方式。您需要处理的唯一不便是鼠标命中测试不再那么简单,您需要将面板的MouseDown事件坐标映射到注释。只需保留一个列表,跟踪每个音符的显示位置。您将使用它进行绘画以及鼠标命中测试。
答案 1 :(得分:1)
在基础控件“MusicStaff”
的子级中添加顶级控件“MusicNote”之后的事情 - 初始化所有组件 -
// mStaff: the MusicStaff object
// mNote: the MusicNote object
mStaff.Children.Add(mNote);
在旧方案中,表单是两者的父级,因此它们在任何透明区域中显示表单背景
修改“MusicNote”的父级后,它会在透明区域中显示“MusicStaff”背景
我希望有所帮助!