问题
I'd like to create a comboBox in visual studio 2019 as presented as shown,
How can I extract the images from the ChartType ComboBox and show list of ChartType in my ComboBox with the images?
回答1:
To get the images you need to extract them from the embedded resources within the compiled .Net assembly. You will need to add using System.Resources;
to your using statements.
Get the manifest stream System.Windows.Forms.DataVisualization.Charting.Design.resources from the assembly containing the Chart System.Windows.Forms.DataVisualization.Charting.Chart
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button2_Click(object sender, EventArgs e)
{
var resourceStream = typeof(System.Windows.Forms.DataVisualization.Charting.Chart)
.Assembly.GetManifestResourceStream("System.Windows.Forms.DataVisualization.Charting.Design.resources");
using (System.Resources.ResourceReader resReader = new ResourceReader(resourceStream))
{
var dictEnumerator = resReader.GetEnumerator();
while (dictEnumerator.MoveNext())
{
var ent = dictEnumerator.Entry;
imageList1.Images.Add($"{ent.Key}", ent.Value as Bitmap);
listView1.Items.Add(new ListViewItem($"{ent.Key}", $"{ent.Key}"));
}
}
}
}
For simplicity I just added it to a ImageList
linked to a ListView
.
listView1.View = View.LargeIcon;
listView1.LargeImageList = imageList1;
listView1.SmallImageList = imageList1
This is the outcome.
To create a combo box with a drop-down
For the combo I looked at this questions
The code: In the while block
...
...
while (dictEnumerator.MoveNext())
{
var ent = dictEnumerator.Entry;
chartSelector1.Items.Add(new ChartDropDownItem($"{ent.Key}",ent.Value as Bitmap));
}
...
...
and the additional classes: (This will create a ChartSelector
control in your toolbox after building the project)
public class ChartDropDownItem
{
public string Value { get; set; }
public Image Image { get; set; }
public ChartDropDownItem(string val, Bitmap img)
{
Value = val;
Image = img;
}
}
public class ChartSelector : ComboBox
{
public ChartSelector()
{
DrawMode = DrawMode.OwnerDrawFixed;
DropDownStyle = ComboBoxStyle.DropDownList;
}
protected override void OnDrawItem(DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
if (e.Index >= 0 && e.Index < Items.Count)
{
ChartDropDownItem item = (ChartDropDownItem)Items[e.Index];
e.Graphics.DrawImage(item.Image, e.Bounds.Left, e.Bounds.Top);
e.Graphics.DrawString(item.Value, e.Font, new SolidBrush(e.ForeColor), e.Bounds.Left + item.Image.Width, e.Bounds.Top + 2);
}
base.OnDrawItem(e);
}
}
and that looks like this:
回答2:
The following is my code without the use of additional classes. This is done with the help of CobyC Answer.
private List<string> dataSourceNames = new List<string>();
private List<Bitmap> dataSourceImage = new List<Bitmap>();
private void loadCombobox1()
{
// Get ChartTypes and Images
var resourceStream = typeof(Chart).Assembly
.GetManifestResourceStream("System.Windows.Forms.DataVisualization.Charting.Design.resources");
using (System.Resources.ResourceReader resReader = new ResourceReader(resourceStream))
{
var dictEnumerator = resReader.GetEnumerator();
while (dictEnumerator.MoveNext())
{
var ent = dictEnumerator.Entry;
dataSourceNames.Add(ent.Key.ToString());
dataSourceImage.Add(ent.Value as Bitmap);
}
}
//Load ChartType Into combobox
comboBox1.DataSource = dataSourceNames;
comboBox1.MaxDropDownItems = 10;
comboBox1.IntegralHeight = false;
comboBox1.DrawMode = DrawMode.OwnerDrawFixed;
comboBox1.DropDownStyle = ComboBoxStyle.DropDownList;
comboBox1.DrawItem += comboBox1_DrawItem;
}
private void comboBox1_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
if (e.Index >= 0)
{
// Get text string
var txt = comboBox1.GetItemText(comboBox1.Items[e.Index]);
// Specify points for drawing
var r1 = new Rectangle(e.Bounds.Left + 1, e.Bounds.Top + 1,
2 * (e.Bounds.Height - 2), e.Bounds.Height - 2);
var r2 = Rectangle.FromLTRB(r1.Right + 2, e.Bounds.Top,
e.Bounds.Right, e.Bounds.Bottom);
//Draw Image from list
e.Graphics.DrawImage(dataSourceImage[e.Index], r1);
e.Graphics.DrawRectangle(Pens.Black, r1);
TextRenderer.DrawText(e.Graphics, txt, comboBox1.Font, r2,
comboBox1.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
}
}
来源:https://stackoverflow.com/questions/63632017/show-list-of-charttype-in-combobox-chart