I would like to ask, how would you print text from a file directly into a pictureBox. Currently, my program is supposed to do that, but it fails, and I think the reason is, that I force the containerBox to the front of the program. The pictureboxes itself are black as of right now, but that is for testing purposes.
Code:
for (int i = 0; i < fileitems.Length; i++)
{
containerBox.Add(new PictureBox());
//PictureBox pBox = new PictureBox();
containerBox[i].Name = "cb" + i;
containerBox[i].Location = new Point(Convert.ToInt32(b*0.05), curB);
containerBox[i].Size = new Size(Convert.ToInt32(b*0.9),Convert.ToInt32(a/5));
containerBox[i].BackColor = Color.Black;
containerBox[i].Dock = DockStyle.Left;
containerBox[i].Anchor = AnchorStyles.None;
//containerBox[i].Paint += PBox_Paint;
j = containerBox[i].CreateGraphics();
using (Font test1 = new Font("Arial", 14))
{
j.DrawString(fileitems[i],test1,Brushes.Blue,new Point(2,2));
}
//this.Controls.Add(containerBox[i]);
//containerBox.Add(pBox);
this.Controls.Add(containerBox[i]);
containerBox[i].BringToFront();
curB = Convert.ToInt32(containerBox[i].Location.Y+(a/5)+25);
}
As you can see, I tried making it so, that I can paint, but then I can't access the file or read the data. Below you see the code in the paint event
Code:
private void PBox_Paint(object sender, PaintEventArgs e)
{
/*
using (Font test1 = new Font("Arial", 14))
{
e.Graphics.DrawString("test", test1, Brushes.Blue, new Point(3, 3));
}*/
}
How can I read the text from the file, then print it to the left side in the picturebox?
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
#Hello guys, I have this problem with Forms in C#, I want to make a font viewer, actually I want to
make two Combobox that make change the "graphics" and display the same name of the font in its style
and in a specific size of the second Combobox. The main problem is that the style and the size don't
change. Any error could be cool for me to be told :) Here is my code.#
namespace CodeImage35
{
class Visualizer : Form
{
Label choose;
PictureBox picbox; //this is for the text
Graphics textm; //the text in PictureBox
ComboBox fontsm; //font of the text
ComboBox size; //size of the font
String fonts; //I used this for get the fonts,maybe never is used
public Visualizer() //Here is the UI
{
this.Width = 600;
this.Height = 300;
this.Text = "Visualizer of fonts";
choose = new Label();
choose.Size = new Size(100, 20);
choose.Location = new Point(20, 20);
choose.Text = "Choose Font:";
picbox = new PictureBox();
picbox.Size = new Size(300, 200);
picbox.Location = new Point(100,150);
fontsm = new ComboBox();
fontsm.Location = new Point(110, 20);
fontsm.Size = new Size(350, 20);
size = new ComboBox();
size.Location = new Point(480, 20);
size.Size = new Size(100, 20);
System.Drawing.Text.InstalledFontCollection fonts = new InstalledFontCollection(); //this
//is for the fonts
foreach ( FontFamily style in fonts.Families )//I add them in the combobox here
{
fontsm.Items.Add(style.Name);
}
for( int s = 1; s <= 50; size++ )
{
size.Items.Add(s); //I add here the sizes from 1 to 50
}
picbox.Paint += new PaintEventHandler(write_in_PictureBox);
Controls.Add(fontsm);
Controls.Add(choose);
Controls.Add(size);
Controls.Add(picbox);
}
void write_in_PictureBox(object sender, PaintEventArgs e)
{
String text2 = fontsm.Text;
textm = e.Graphics;
int x = 0;
Int32.TryParse(size.Text, out x); //I tried with this function to make string to int for
//the parameter of "DrawString
textm.DrawString( text2 , new Font( text2, x ), Brushes.Black, new Point(10, 10) );
}
}
static class MainClass
{
static void Main()
{
Visualizer screen1 = new Visualizer();
Application.Run(screen1);
}
}
}
To begin fix this compiler error:
for( int s = 1; s <= 50; size++ )
{
size.Items.Add(s); //I add here the sizes from 1 to 50
}
the correct variable to increment is s . Also you cold avoid to start from 1, a value really too small to render a font and appreciate the result. Starting from 6 or 8 should be fine. Apart from that...
In order to draw a string, based on the input of the two combobox, you have to handle the SelectedValueChanged event (or SelectedIndexChanged). Those events happen when the user change (select) a value in the combobox.
Instead, the PaintEventHandler happens when a control is being painted. See Paint event.
Following your example you can attach the SelectedValueChanged event to a method that draws the string like you did in write_in_PictureBox method .
//put this at the end of the constructor method.
//The event will be triggered on both combobox, allowing the user to see the result of it's selection whatever combobox is edited
fontsm.SelectedValueChanged += (sender, args) => DrawFont();
size.SelectedValueChanged += (sender, args) => DrawFont();
//that's just a method to handle the event
private void DrawFont()
{
using (var g = picbox.CreateGraphics()) //remember to always dispose a disposable resource
{
//clear the area before draw the new string
g.Clear(DefaultBackColor);
if (!Int32.TryParse(size.Text, out int x)) x = 12; //if no value is selected for size combobox, use 12 as default
string text = fontsm.Text;
g.DrawString(text, new Font(text, x), Brushes.Black, new Point(10, 10));
}
}
By the way... if you just want to show a font preview... it would be much easier for you to just put a label and change it's text and font property :) .
I am creating dynamic PictureBox and label in WinForms. For this I have created a method which creates these items on the basis of given integer. In the first run while loading the form, its works smoothly, but when I pass any integer from a dropdown box, it does not make any changes. I tried debugging the code, and all the labels are created accordingly but it is not reflected in the winForm. I tried using Invalidate, Update, Refresh but non of them worked.
Here is the method that I have implemented.
private void createPictureBox(int size)
{
//this.Controls.Clear();
panel1.Controls.Clear();
Label[] ParameterLabel = new Label[size];
PictureBox[] ParameterBack = new PictureBox[size];
int y_value = 11;
this.Refresh();
for (int i = 0; i < size; ++i)
{
ParameterLabel[i] = new Label();
ParameterLabel[i].Text = "Test Text";
ParameterLabel[i].Font = new System.Drawing.Font("Calibri", 8, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(128)));
ParameterLabel[i].ForeColor = System.Drawing.Color.White;
ParameterLabel[i].BackColor = System.Drawing.Color.FromArgb(1, 0, 64);
ParameterLabel[i].Size = new System.Drawing.Size(145, 20);
ParameterLabel[i].Location = new Point(30, y_value);
ParameterLabel[i].Anchor = AnchorStyles.Left;
ParameterLabel[i].Visible = true;
ParameterBack[i] = new PictureBox();
ParameterBack[i].Image = Image.FromFile(STR_SETTING_PATH + "\\" + STR_IDEA_NO_XXXXX + "_01_nv.png");
ParameterBack[i].Size = new System.Drawing.Size(400, 32);
ParameterBack[i].Location = new Point(2, y_value - 10);
ParameterBack[i].Anchor = AnchorStyles.Left;
ParameterBack[i].Visible = true;
//this.Controls.Add(ParameterBack[i]);
y_value += 37;
}
panel1.Controls.AddRange(ParameterLabel);
panel1.Controls.AddRange(ParameterBack);
panel1.Invalidate();
}
Who can you distinguish between controls created in the first call and those created in other calls? I've tested your function with a tiny change, it seems to be working fine:
int CallIndex = 0; // this is on the form level
private void button1_Click(object sender, EventArgs e)
{
createPictureBox(3);
CallIndex += 1;
}
private void createPictureBox(int size)
{
// this has the exact same code as your method (copy-paste into my visual studio),
// except this change:
// ParameterLabel[i].Text = "Test Text";
ParameterLabel[i].Text = string.Format("Test {0}", CallIndex); // instead of the row above
}
I did remove the previously added controls and added the new one after which apparently solved my problem. The problem was due to piling of Controls one over another. I first removed the previously created controls using
this.Controls.Remove(UserControl1);
Then re-created its instance, which solved my problem.
I created around 12 picbox and label dynamically im able to retrieve data in the picbox and label from SQL. the picbox image in binary format and the row where imagestore in table also contain image title's in database.
The problem is that I want to add a click_event on picbox. ASAP I click on picbox a textbox1. text which I created must show the title of the image which is store in the SQL.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.OleDb;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace library
{
public partial class showingmore : Form
{
private string passvalue;
public string passval
{
get { return passvalue; }
set { passvalue = value; }
}
public showingmore()
{
InitializeComponent();
}
MemoryStream ms;
byte[] photo_aray;
private void showingmore_Load_1(object sender, EventArgs e)
{
OleDbConnection con = new OleDbConnection("Provider=SQLOLEDB;User ID=sa;Password =12345678; Initial Catalog=library; server=raj; TRUSTED_CONNECTION=true;");
OleDbDataAdapter Adap = new OleDbDataAdapter("select * from movie ", con);
textBox1.Text = passvalue;
DataSet ds = new DataSet();
Adap.Fill(ds);
//textBox1.Text = ds.Tables[0].Rows[15][0].ToString(); // the working way to use ds to fill data
//textBox1.Text = ds.Tables[0].Rows[1];
//int icount = ds.Tables[0].Rows.Count;
//textBox1.Text = icount.ToString();
/**** Creating Label's and Picture Box ****/
int n = 12; // total time for running loop.
int j = 14; // y-axis co-ordinate label
int k = 479; // x-axis co-ordinate label
int l = 18; // y-axis co-ordinate label
// Creating label through loop's.
for (int i = 0; i < n; i++)
{
//Create label
Label labels = new Label();
PictureBox picbox = new PictureBox();
labels.Text = ds.Tables[0].Rows[i][0].ToString();
if (i <= 5)
{
//Position label on screen
labels.Location = new Point(j, k);
j = j + 228;
// Label text color
labels.ForeColor = Color.Gainsboro;
}
else
{
k = 782; // x-axis co-ordinate
labels.Location = new Point(l, k);
l = l + 228;
labels.ForeColor = Color.Gainsboro;
}
this.Controls.Add(labels);
}
n = 12; // total time for running loop.
j = 18; // y-axis co-ordinate
k = 246; // x-axis co-ordinate
l = 18; // y-axis co-ordinate
// Creating PictureBox through loop's.
for (int i = 0; i < n; i++)
{
//Create PictureBox
PictureBox picbox = new PictureBox();
picbox.Image = null;
if (ds.Tables[0].Rows[i][14] != System.DBNull.Value)
{
photo_aray = (byte[])ds.Tables[0].Rows[i][14];
MemoryStream ms = new MemoryStream(photo_aray);
picbox.Image = Image.FromStream(ms);
}
if (i <= 5)
{
//Position PictureBox on screen
picbox.Location = new Point(j, k);
picbox.Size = new Size(161, 220);
picbox.BackColor = Color.Gainsboro;
j = j + 228;
}
else
{
k = 543; // y-axis co-ordinate
picbox.Location = new Point(l, k);
picbox.Size = new Size(161, 220);
picbox.BackColor = Color.Gainsboro;
l = l + 228;
}
this.Controls.Add(picbox);
}
}
}
}
To get the click event for your dynamically created PictureBox, you can simple subscribe to the click event when you create it;
private void createPicBoxes()
{
for (int i = 0; i <= 12; i++)
{
PictureBox picBox = new PictureBox();
picBox.Click += picBox_Click;
}
}
static void picBox_Click(object sender, EventArgs e)
{
//do your stuff here which handles generically all of your picture boxes clicks.
}
In short, subscribing to the controls events like such means that whenever that action is performed, in your case a click event, the attached method will fire off.
Put this somewhere in the loop before adding the picbox to the Controls collection:
picbox.MouseClick += picbox_MouseClick;
Then, implement the handler for the click somewhere in your showingmore class:
private void picbox_MouseClick(object sender, MouseEventArgs e)
{
// Your code here.
}
Add event handler to the PictureBox when creating it.
Something like below
PictureBox picbox = new PictureBox();
picbox.Click += new EventHandler(this.picbox_Click);
void picbox_Click(object sender, System.EventArgs e)
{
//your code...
}
I got a problem with my WinForms-Application; I want to Drag&Drop a Outlook Mail into a RichTextBox. I found many articles about the Drag&Drop function but they all insert the Mailtext into the rTB (see: Link).Actually I can insert document like .txt, .jpg, Outlook-mails from desktop... to my program. My richTextBox automatic generate an image for the file and insert this image on a position. Like:
.
After the user Drag and Drop the file a image will be created on the Drop position and if the user double click the image the file will be opened.
PROBLEM:
The program work fine, but if I try to drag a mail out of Outlook, the program insert the mailbody to the richTextBox and no as an image.
I have saved one Mail on the desktop and try to insert this mail to my program. The following output is given in my richTextBox (would be perfect):
Mailicon from desktop per Drag&Drop:
Otherwise I tried to Drag&Drop a mai from Outlook to my program and the following output is given (Just look at the text and not the images:
Mail from Outlook per Drag&Drop (THE PROBLEM!!!):
The Programm insert the cc/mailadress and Mailbody to the rTB.
Here is the code behind: (My richTextBox is a own created richTextBox called "MyRichTextBox" Download the project under: link_RICHTEXTBOX. )
CODE
private void Form1DragDrop(object sender, DragEventArgs e)
{
Startup();
//Microsoft.Office.Interop.Outlook.ApplicationClass oApp =
// new Microsoft.Office.Interop.Outlook.ApplicationClass();
Microsoft.Office.Interop.Outlook.Explorer oExplorer = _Outlook.ActiveExplorer();
Microsoft.Office.Interop.Outlook.Selection oSelection = oExplorer.Selection;
foreach (object item in oSelection)
{
Microsoft.Office.Interop.Outlook.MailItem mi = (Microsoft.Office.Interop.Outlook.MailItem)item;
rTB_test.Text = mi.Body.ToString();
string mailName = "Mail\n" + (mailList.Count + 1);
// load an image with enough room at the bottom to add some text:
Image img = Image.FromFile(Imagepath);
// now we add the text:
int width = img.Width;
using (Graphics G = Graphics.FromImage(img))
using (Font font = new Font("Arial", 7f))
{
SizeF s = G.MeasureString(mailName, font, width);
G.DrawString(mailName, font, Brushes.Black,
(width - s.Width) / 2, img.Height - s.Height - 1);
}
// adding the image is easy only if we use the clipboard..
Clipboard.SetImage(img);
// now insert image
rTB_test.Paste();
// now we can get a hashcode as a unique key..
// ..we select the image we have just inserted:
rTB_test.SelectionStart = rTB_test.TextLength - 1;
rTB_test.SelectionLength = 1;
// finally we need to store the mail itself with its key:
mailList.Add(rTB_test.SelectedRtf.GetHashCode(), mi);
// cleanup: unselect and set cursor to the end:
rTB_test.SelectionStart = rTB_test.TextLength;
rTB_test.SelectionLength = 0;
}
Microsoft.Office.Interop.Outlook.Application _Outlook = null;
Dictionary<int, Microsoft.Office.Interop.Outlook.MailItem> mailList =
new Dictionary<int, Microsoft.Office.Interop.Outlook.MailItem>();
private void rTB_test_DoubleClick(object sender, EventArgs e)
{
var ss = rTB_test.SelectionStart;
var sl = rTB_test.SelectionLength;
int hash = rTB_test.SelectedRtf.GetHashCode();
// a few checks:
if (sl == 1 && mailList.Keys.Contains(hash))
{
Microsoft.Office.Interop.Outlook.MailItem mi = mailList[hash];
// do stuff with the msgItem..
// ..
}
}
void lbl_MouseDoubleClick(object sender, MouseEventArgs e)
{
Microsoft.Office.Interop.Outlook.MailItem mi =
(Microsoft.Office.Interop.Outlook.MailItem)((Label)sender).Tag;
// code to process the doubleclicked mail item..
}
void Startup()
{
_Outlook = new Microsoft.Office.Interop.Outlook.Application();
}
private void Form1_DragEnter(object sender, DragEventArgs e)
{
e.Effect = DragDropEffects.Copy;
}
After the user double click on the picture the mail should be opened in Outlookexplorer.
UPDATE
If I use the code from TaW´s answer the following output is given:
After I double click the icon the mail won´t be open... So the code from the answer is just a "iconcreation".
Thank you in advanced!
Here is what I meant in my comments:
private void Form1DragDrop(object sender, DragEventArgs e)
{
Startup();
Microsoft.Office.Interop.Outlook.ApplicationClass oApp =
new Microsoft.Office.Interop.Outlook.ApplicationClass();
Microsoft.Office.Interop.Outlook.Explorer oExplorer = _Outlook.ActiveExplorer();
Microsoft.Office.Interop.Outlook.Selection oSelection = Explorer.Selection;
foreach (object item in oSelection)
{
Microsoft.Office.Interop.Outlook.MailItem mi =
(Microsoft.Office.Interop.Outlook.MailItem)item;
// rTB_test.Text = mi.Body.ToString();
Label lbl = new Label();
lbl.AutoSize = false;
lbl.Size = new Size( 80, 50); // <-- your choice!
lbl.Text = someText; // <-- your choice!
lbl.TextAlign = ContentAlignment.BottomCenter;
lbl.Image = someImage; // <-- your choice!
lbl.ImageAlign = ContentAlignment.TopCenter;
int count = rTB_test.Controls.Count;
int itemsPerRow = rTB_test.Width / 80;
lbl.Location = new Point( (count % itemsPerRow) * 80,
count / itemsPerRow * 50);
lbl.Tag = mi; // store the data object
lbl.MouseDoubleClick += lbl_MouseDoubleClick;
lbl.Parent = rTB_test; // add to the RTF's Controls
}
}
void lbl_MouseDoubleClick(object sender, MouseEventArgs e)
{
Microsoft.Office.Interop.Outlook.MailItem mi =
(Microsoft.Office.Interop.Outlook.MailItem) ( (Label)sender).Tag;
// code to process the doubleclicked mail item..
}
These Labels will sit on top of any Text in the RTB without interfering with it. If you want to, you can modify the code for the Location to move them out of the way or style the Labels in many other ways..
Update
After the last remarks the problem get a lot clearer: other parts of the application are already adding mail icons to the RTB and we shall add more 'of the same'..
Adding an Image is best done via the clipboard; here is code that will do that:
// create some test text, maybe extract it from the mailheader?..
string mailName = "Mail\n" + (mailList.Count + 1);
// load an image with enough room at the bottom to add some text:
Image img = Image.FromFile(yourMailImageFile);
// make the images unique by embedding a counter in a bright pixel:
img = (Image)fingerPrintID((Bitmap)img, 250 - mailList.Count); //*1*
// now we add the text:
int width = img.Width;
using (Graphics G = Graphics.FromImage(img))
using (Font font = new Font("Arial", 7f))
{
SizeF s = G.MeasureString(mailName, font, width);
G.DrawString(mailName, font, Brushes.Black,
(width - s.Width) / 2, img.Height - s.Height - 1);
}
// adding the image is easy only if we use the clipboard..
Clipboard.SetImage(img);
// insert only at the end!
rTB_test.SelectionStart = rTB_test.TextLength;
rTB_test.SelectionLength = 0;
// now insert image
rTB_test.Paste();
// now we can get a hashcode as a unique key..
// ..we select the image we have just inserted:
rTB_test.SelectionStart = rTB_test.TextLength - 1;
rTB_test.SelectionLength = 1;
// retrieve the counter id:
string id = GetID(rTB_test.SelectedRtf); //*2*
// finally we need to store the mail itself with its key:
mailList.Add(id, mi);
// cleanup: unselect and set cursor to the end:
rTB_test.SelectionStart = rTB_test.TextLength;
rTB_test.SelectionLength = 0
We need to create a Dictionary to store our mails:
Dictionary<string, Microsoft.Office.Interop.Outlook.MailItem> mailList =
new Dictionary<string, Microsoft.Office.Interop.Outlook.MailItem>(); // *3*
Here is how we can access the mails in the DoubleClick event:
private void rTB_test_DoubleClick(object sender, EventArgs e)
{
var ss = rTB_test.SelectionStart;
var sl = rTB_test.SelectionLength;
string id = GetID(sr); //*4*
// a few checks:
if (sl == 1 && mailList.Keys.Contains(id) && sr.Contains(#"{\pict\") )
{
Microsoft.Office.Interop.Outlook.MailItem mi = mailList[id];
// do stuff with the msgItem, e.g..
mi.Display();
}
}
Here is the result along with the image I use:
Note that in addition to adding the image we also store the both the mail data and the position of the image in the RTB in a Dictionary.
Update 2: I have replaced the position of the image as key with a HashCode of its RtfText; this is robust to any changes in the rest of the RTF's content. However, it relies on the images being unique, so adding an index to their text as in the code is recommended. (Or setting a few random pixels, maybe based on a GUID..)
Update 3 & 4: (*1* - *6*)
We found that we need to make the key resilient to several changes, like fonts surrounding the icon, which will influence the Rtf code, or the user enlarging the image.
Here is a FingerPrint function, which will make the images we add in unobtrusivly unique by setting a few pixels at the top of the image. Three to set a marker and one to set an ID:
Bitmap fingerPrintID(Bitmap bmp, int key) //*5*
{
for (int i = 0; i < 3; i++)
{
bmp.SetPixel(i, 0, Color.FromArgb(255, 238,238,238)); // EE EE EE
}
bmp.SetPixel(3, 0, Color.FromArgb(255, key, key, key));
return bmp;
}
And to retrieve this function will pull the 3 hex digits as string from the RTF code:
string GetID(string Rtf) //*6*
{
int x = Rtf.IndexOf("eeeeeeeeeeeeeeeeee"); // 238 238 238
if (x < 0) return "";
string hex = Rtf.Substring(x +18, 6);
return hex;
}
I chose the pixels to be rather bright; if you know which image you use, you can optimze the color choice even more.. With the new string id, we don't need the GetHashcode calls..
I have 4 Picture box loading images. I want to select these images based on mouse click. For example If I click images from picturebox 1 and 2, I want to get images from these picturebox 1 and 2 only.The function look like Gallery in Android phones.
it is not very difficult. create pictureBoxes dynamically, add them the same Click handler and store images from selected pictureBox
e.g. gallery form (last picture is selected)
public partial class GalleryForm : Form
{
// stores selected images in order of adding
private readonly List<Image> _gallery = new List<Image>();
private readonly Random _rnd = new Random();
// handle pics layout on form
private readonly FlowLayoutPanel flowPanel;
public GalleryForm()
{
InitializeComponent();
Name = "GalleryForm";
Text = "Gallery";
ClientSize = new Size(276, 274);
// flowPanel will contain picture boxes with images
flowPanel = new FlowLayoutPanel();
flowPanel.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left| AnchorStyles.Right;
flowPanel.Location = new Point(12, 12);
flowPanel.Name = "flowPanel";
flowPanel.Size = new Size(252, 250);
int picsCount = 4;
var picSize = new Size(100, 100);
var imSize = new Size(50, 50);
// creates required number of picture boxes with simple images
for (int p = 0; p < picsCount; p++)
{
var picBox = new PictureBox();
picBox.Name = "pic" + (p+1).ToString();
picBox.Size = picSize;
picBox.SizeMode = PictureBoxSizeMode.Zoom;
picBox.Image = GetImage(p, imSize);
picBox.Click += ClickOnImage;
flowPanel.Controls.Add(picBox);
}
Controls.Add(flowPanel);
}
// click handler
private void ClickOnImage(object sender, EventArgs eventArgs)
{
var picBox = (PictureBox) sender;
if (_gallery.Remove(picBox.Image))
// if _gallery contained image, remove selection
picBox.BorderStyle = BorderStyle.None;
else
{
// add selection
picBox.BorderStyle = BorderStyle.Fixed3D;
// add image to _gallery
_gallery.Add(picBox.Image);
}
}
// creates image with solid background
private Bitmap GetImage(int p, Size s)
{
var bmp = new Bitmap(s.Width, s.Height);
using (Graphics gr = Graphics.FromImage(bmp))
gr.Clear(Color.FromArgb(_rnd.Next(255), _rnd.Next(255), _rnd.Next(255)));
return bmp;
}
}