总览
我目前正在为我的应用程序开发一个主题系统,允许用户选择浅色和深色主题(类似于Visual Studio)。整个过程是非常简单的,这是我如何改变BackColor
的财产ListView
目前控制(虽然我已经尝试了几个在线的解决方案未能如刚刚设置BackColor
的ListView
和ListViewItem
)。
分解
我有ImageList
6张图片;所有这些都有透明的背景。每个图像都是不同颜色的玻璃球和阴影的图像。我根据从数据库中提取的状态,将这六个图像之一分配给ListViewItem
我的ListView
(设置为Details
查看)控件中的每个。
只要将ListView
和ListViewItem
分配给图像并将其BackColor
属性设置为,一切都会很好Color.Control
。如果更改为其他任何颜色(绿色,灰色,蓝色,红色等);则图像的底色不匹配。它继续保留默认Color.Control
颜色。
主题代码
public static void ApplyTheme(Form f) {
foreach (Control c in f.Controls) {
if (c is MenuStrip)
ThemeMenu((MenuStrip)c);
else {
ApplyStyles(c);
if (c.Controls != null || c.Controls.Count > 0)
RecurseChildControls(c);
}
}
}
public static void RecurseChildControls(Control parent) {
foreach (Control child in parent.Controls) {
ApplyStyles(child)
if (child.Controls != null || child.Controls.Count > 0)
RecurseChildControls(child);
}
}
public static void ApplyStyles(Control c) {
if (c is Button) {
Button b = (Button)c;
b.FlatStyle = FlatStyle.Flat;
b.FlatAppearance.BorderSize = 0;
}
if (c is RoundedPanel || c is PictureBox) {
// Do nothing.
} else {
if (c is Label) {
if (c.Parent is RoundedPanel) {
// Do nothing.
} else {
c.BackColor = BackColor;
c.ForeColor = ForeColor;
}
} else {
c.BackColor = BackColor;
c.ForeColor = ForeColor;
}
if (c is ListView) {
ListView lv = (ListView)c;
if (Style = Themes.Dark)
lv.GridLines = false;
foreach (ListViewItem lvi in lv.Items) {
lvi.BackColor = BackColor;
lvi.ForeColor = ForeColor;
}
}
}
}
我尝试添加一个方法来更新控件及其所有对象的BackColor
属性,然后在和事件上调用此方法(均不起作用);在更改a的属性后立即调用此方法代替的方法;我什至尝试调用表单本身并重新绘制所有内容。ListView
ListViewItem
DrawItem
DrawSubItem
Invalidate
ListView
ImageIndex
ListViewItem
Invalidate
我真的可以在这方面使用一些指导,因为到目前为止其他所有工作都很好。这是让我转圈的唯一问题。我浏览过Google几次,但从未找到与图片BackColor
包含ListView
或的图片不相关的任何结果ListViewItem
。也许我没有使用正确的词来执行搜索,或者也许我是第一个抱怨这个问题的人。谁知道。任何帮助表示赞赏。
注意
如果您觉得我没有任何必要的信息,或者在某些事情上我应该更加清楚,请随时发表评论并告诉我,以便我为以后的读者更新该文章的清晰度。
新尝试(失败)
ListView
在设置ImageIndex
属性之前(和之后)更改对象的背景颜色。OwnerDraw
和DrawItem
事件绘制图像。Bitmap
具有指定背景色的原始图像,如下所示尝试密码
// Bullet 2
e.Graphics.DrawImage(Image, Rectangle);
// Bullet 3
Rectangle r = new Rectangle(0, e.Bounds.Y, 16, 16);
Image I = imageList1.Images[e.Item.ImageIndex];
Bitmap b = new Bitmap(i.Width, i.Height);
using (Graphics g = Graphics.FromImage(b)) {
g.Clear(Theme.BackColor);
g.DrawImageUnscaledAndClipped(i, new Rectangle(Point.Empty, i.Size));
}
e.Graphics.DrawImage(b, r);
图片
在目前的结果,其中绿点为图像,红点是背景的问题,蓝框是ListViewItem
。
要ListViewItem.BackColors
在图片下方显示个人,您需要所有者绘画,否则ListView.BackColor
将显示。但是您注意到图像的半透明部分中存在难看的伪影。
经过无数次测试,我相信ImageList
是罪魁祸首。
似乎在应该是半透明像素的地方插入了灰色像素。完全透明的像素不受影响。
这独立于其属性而发生。
这是所有者ListView
从中绘制一次图像的结果ImageList
,一次绘制相同图像但直接从磁盘加载的结果。
您肯定可以看到哪个。
图像是透明背景上的黄色斑点,具有半透明的光晕和两个半透明的孔。
ListView.DrawItem
事件中的绘图代码相同:
e.DrawBackground();
e.DrawText();
Rectangle rect = new Rectangle(0, e.Bounds.Y, 32, 16);
Bitmap bmp1 = (Bitmap)imageList1.Images[e.Item.ImageIndex];
Bitmap bmp2 = (Bitmap)Bitmap.FromFile("filepath.png");
e.Graphics.DrawImage(bmp1_OR_bmp2, rect);
因此,如果您需要图像中的半透明性,则不能真正将它们存储在中ImageList
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句