I am working on a project in c# using windows forms.
me and the group I am in want to make it so that when the user hovers their mouse over an image, in our case a card, that a larger image of that card appears next to the mouse arrow, much in the same way a tool tip would work.
I don't think you can use a tool tip to do this i have tried looking everywhere,
any advice or examples would be great thank you very much
You may want to look at this Code Project Article
It shows you how to create an OwnerDrawn ToolTip with an Image.
Thanks for the responses I got everything figured out.
What I wanted to do was that when I moused over a certain area a different image for that area would popup in the same way that a tool tip did. So after some research I figured out how to create my own tool tip class.
here's an example.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
CustomToolTip tip = new CustomToolTip();
tip.SetToolTip(button1, "text");
tip.SetToolTip(button2, "writing");
button1.Tag = Properties.Resources.pelican; // pull image from the resources file
button2.Tag = Properties.Resources.pelican2;
}
}
class CustomToolTip : ToolTip
{
public CustomToolTip()
{
this.OwnerDraw = true;
this.Popup += new PopupEventHandler(this.OnPopup);
this.Draw +=new DrawToolTipEventHandler(this.OnDraw);
}
private void OnPopup(object sender, PopupEventArgs e) // use this event to set the size of the tool tip
{
e.ToolTipSize = new Size(600, 1000);
}
private void OnDraw(object sender, DrawToolTipEventArgs e) // use this to customzie the tool tip
{
Graphics g = e.Graphics;
// to set the tag for each button or object
Control parent = e.AssociatedControl;
Image pelican = parent.Tag as Image;
//create your own custom brush to fill the background with the image
TextureBrush b = new TextureBrush(new Bitmap(pelican));// get the image from Tag
g.FillRectangle(b, e.Bounds);
b.Dispose();
}
}
}
A simple way to do is to hide/show a picture box at specified location. Another method is to load & draw (paint) an image using GDI API.
Related
I'm working on redesigning an older application to make it more user-friendly. One addition I would like to make is, when hovering over a specific button, a ~(200, 200) demonstrative GIF appears to the bottom right of the cursor (similar to the functionality of a ToolTip).
I looked into the modification of the ToolTip class, which seems excessive. The above mentioned would be ideal, though I am considering a static imageBox that appears after a hovering for 2 or so seconds.
Could anyone lead me in the right direction?
Take a look at this article, it details out the steps of the image in a tooltip https://www.codeproject.com/Articles/42050/ToolTip-With-Image-C
And this method in particular:
void CustomizedToolTip_Draw(object sender, DrawToolTipEventArgs e)
{
e.Graphics.CompositingQuality = CompositingQuality.HighQuality;
myToolTipRectangle.Size = e.Bounds.Size;
e.Graphics.FillRectangle(myBorderBrush, myToolTipRectangle);
myImageRectangle = Rectangle.Inflate(myToolTipRectangle,
-BORDER_THICKNESS, -BORDER_THICKNESS);
e.Graphics.FillRectangle(myBackColorBrush, myImageRectangle);
Control parent = e.AssociatedControl;
Image toolTipImage = parent.Tag as Image;
if (toolTipImage != null)
{
myImageRectangle.Width = myInternalImageWidth;
myTextRectangle = new Rectangle(myImageRectangle.Right, myImageRectangle.Top,
(myToolTipRectangle.Width - myImageRectangle.Right - BORDER_THICKNESS),
myImageRectangle.Height);
myTextRectangle.Location =
new Point(myImageRectangle.Right, myImageRectangle.Top);
e.Graphics.FillRectangle(myBackColorBrush, myTextRectangle);
e.Graphics.DrawImage(toolTipImage, myImageRectangle);
e.Graphics.DrawString(e.ToolTipText, myFont,
myTextBrush, myTextRectangle, myTextFormat);
}
else
{
e.Graphics.DrawString(e.ToolTipText, myFont,
myTextBrush, myImageRectangle, myTextFormat);
}
}
I am trying to create a Bitmap from a RichTextBox and set it as the background image for a panel, but unfortunately the text is not shown.
Bitmap l_bitmap = new Bitmap(m_control.Width, m_control.Height);
m_control.DrawToBitmap(l_bitmap, new Rectangle(0, 0, l_bitmap.Width, l_bitmap.Height));
m_panel.BackgroundImage = l_bitmap;
m_panel.Refresh();
m_control is my RichTextBox. When I debug, I can see that the control contains the text I wrote, but the bitmap just shows an empty RichTextBox.
I use the same code for other types of controls (Button, CheckBox, TextBox...). The text is shown with no problems.
Well you are trying to create a bitmap from the control. The text you put in there isn't the control, so it won't bother to chow it as bitmap. Try to create a picture from screen (like a screenshot).
Example:
Graphics gr = Graphics.FromImage(l_bitmap);
gr.CopyFromScreen(m_control.PointToScreen(Point.Empty), point.Empty, m_control.Size);
This will make a bitmap from your given points. This will additional show you the text.
EDIT
Maybe you can use this instead. In addition to your idea, I simply put a label onto my panel. (L for Label and P for Panel)
As you can see, the label is empty because I cleared the Text property. Now, when you click one of the buttons below the panel, it will update the label.Text propertie and there will be the text you gave the control.
Here is some example:
As you can see, the label shows the Name of the control. Completly custom as you can see on my source code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public RichTextBox tmpRtf = new RichTextBox();
//Poor button name incoming...
private void button1_Click(object sender, EventArgs e)
{
if (tmpRtf == null)
tmpRtf = new RichTextBox();
//You can add any text here and it will be shown on the label.
this.tmpRtf.Text = "Richtextbox";
this.UpdatePanel(this.tmpRtf);
}
//Custom method to update the panel for any control. Can pobably be done way better than this, but hey.
private void UpdatePanel(object pControl)
{
//Checks if control is a rtf
if(pControl is RichTextBox)
{
//This is your code! Ay.
Bitmap l_bitmap = new Bitmap(this.panel1.Width / 2, this.panel1.Height / 2);
(pControl as RichTextBox).DrawToBitmap(l_bitmap, new Rectangle(0, 0, l_bitmap.Width, l_bitmap.Height));
this.tmpRtf.BackColor = Color.LightGray;
this.panel1.BackgroundImage = l_bitmap;
this.panel1.BackgroundImageLayout = ImageLayout.Center;
this.labelControlName.Text = this.tmpRtf.Text;
this.panel1.Refresh();
}
}
}
Its not possible to show text on a control thats not visualized. But you can build a workaround! Or, instead of taking a picture you can simply create the control on top of it, that will also show the Text and maybe the user can test it (e.g. click on buttons, look at the control behaviour).
Hopefully this is something to get you inspired that there are always more ways to accomplish.
I inserted an image into a button, but it's not a background image. So, I want to resize the image's size that I want for example Height=30, Width=20 or sometime Height=50, Width=50. Some people told me that it's impossible to resize an image in a button if I inserted it as an background image it's possible.However, if I insist to resize the image it's possible? I don't believe that nobody can do it.
Is this a windows form application? Forgive me if I didn't understand the question, but you should be able to resize the image from the Properties menu if you're using a PictureBox. Right-click on the image you inserted, select properties and there should be a field for Size.
I am assuming that you want to resize the image present inside the button. You can try something like this in Designer File:
//
// ButtonName
//
this.ButtonName.AutoSize = false;
Image image = new Bitmap(customWidth,customHeight);
using (Graphics g = Graphics.FromImage(image )) {
g.DrawImage(FileLocation, 0, 0, customWidth, customHeight);
}
this.ButtonName.Image = image;
This will help in button resizing but the picture won't be clear if much increased.
Button.Resize += Button_Resize;
private void Button_Resize(object sender, EventArgs e)
{
Button button = (Button)sender;
Image resize = new Bitmap(button.Image,new Size(button.Image.Width, (button.Height - 13))); button.Image = resize;
}
I am creating my textbox programmatically in a console application that builds a form window on the fly. I am trying to get Input boxes such as the textbox to show up invisible but still allow the user to input data such as username and password or any other customisation fields I provide. This is for a game launcher and I am attempting to make it NOT look like a windows component.
I have tried some of the solutions on the post below.
Transparency for windows forms textbox
EDIT: As you can see above I have already cited that this does not solve my issue. I do not use the form designer as it has a nasty habit of deleting my code because I presume "It knows better".
The Accepted answer for that does not work for me as I do not use the form designer and InitializeComponent();
Does not work it just tells me that it is not a function of the component.
I have gotten as far as this.
using System.Windows.Forms;
namespace Launcher_Namespace
{
public class TransparentTextBox : TextBox
{
public TransparentTextBox()
{
this.SetStyle(ControlStyles.SupportsTransparentBackColor, true);
}
}
}
And in the main body of code that initialises fields
//Initialise Inputs
_username = new TransparentTextBox();
_username.Bounds = new Rectangle(120, 10, 120, 21);
_username.BackColor = Color.Transparent;
_username.BorderStyle = 0;
_username.Visible = false;
But all this has achieved is allow me to set _username.BackColor = Color.Transparent; Without throwing an error. The Input box remains White with no border. I just want to make the background transparent. Even MSDN recomends this solution but It does not work for me. My only solution left is to build a custom Label class that grabs the inputs and reads the key inputs and adds them to the .Text property but I don't want to do this.
The solution in your linked answer works fine. If you're not using the designer it doesn't matter... you can still use the same solution. InitializeComponent() is simply a method that's created by the code generator in the designer file. If you ever want to know what it does to create controls (it can be very informational to have a look) then create a control using the designer and then inspect the .Designer.cs file.
EDIT: It acts a little funny. You can override OnPaint to fix the white background and disappearing text, see below. Not a "finished" implementation, the cursor doesn't seem to know where to go, but this should get you in the right direction.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
for (int i = 0; i < 3; i++)
{
var x = new UserControl1 {Location = new Point(0, i*20)};
this.Controls.Add(x);
}
}
}
public class UserControl1 : TextBox
{
public UserControl1()
{
SetStyle(ControlStyles.SupportsTransparentBackColor |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.UserPaint, true);
BackColor = Color.Transparent;
TextChanged += UserControl2_OnTextChanged;
}
protected override void OnPaint(PaintEventArgs e)
{
var backgroundBrush = new SolidBrush(Color.Transparent);
Graphics g = e.Graphics;
g.FillRectangle(backgroundBrush, 0, 0, this.Width, this.Height);
g.DrawString(Text, Font, new SolidBrush(ForeColor), new PointF(0,0), StringFormat.GenericDefault);
}
public void UserControl2_OnTextChanged(object sender, EventArgs e)
{
Invalidate();
}
}
}
When we use SetStyle(ControlStyles.UserPaint,true) Control Border Doesn't paint. I did this in Textbox. My textbox border style is FixedSingle but after using setstyle with UserPaint Textbox border is not drawn. Textbox appears like border is set to None.
If this is a dumb question, forgive me. I have a small amount of experience with C#, but not to this degree yet.
I have a series of images that I want to put into a grid with space around each image, also text beneath them and I want them to be clickable, so when they're clicked they hilite, and double click runs an event. The best example I have for this is the user interface of the program ACDSee. I've googled this for hours, and haven't come up with anything applicable. Is this difficult or simple? Can anyone give me an example, or point me in the right direction?
Cheers.
It doesn't seem to be very difficult. I would suggest the following steps:
Add a new "User Control" to your project for image thumbnails. It can contain a docked PictureBox and a Label or LinkLabel at its bottom.
For the space around each thumbnail simply play with the Padding property of the user control.
For the so called grid that is going to hold the thumbnails, use a FlowLayoutPanel, and simply add instances of the above mentioned user-control to this panel.
For visual representation of being selected, change the background color of the user-control instance to blue (for example), and back to control-face when deselected. It is recommended to implement an IsSelected property for the user-control as well.
To emulate thumbnail selection, handle the Click event of the user-control and assign the events for all thumbnail instances to a single event-handler method. Store a global reference to the already selected thumbnail, name it e.g., SelectedThumbnail initialized with null. In the event-handler body compare the sender with the global SelectedThumbnail, and update it if required. If the user-control associated with the sender is not selected (i.e., its background is not blue, or IsSelected is false) make it selected, or change its background. Otherwise change the background to its default color (e.g., control-face).
The Click event handler body looks something like this:
MyThumbnailControl ctrl = sender as MyThumbnailControl;
if(ctrl == null) return;
if(ctrl == SelectedThumbnail) return; // selected again
if(ctrl != SelectedThumbnail)
{
ctrl.IsSelected = true;
ctrl.BackColor = Color.Blue;
// it's better to set the back-color in the IsSelected property setter, not here
SelectedThumbnail.IsSelected = false;
SelectedThumbnail.BackColor = Color.Control;
SelectedThumbnail = ctrl; // important part
}
It's also recommended that all thumbnail instances that are going to be added to the so-called grid, be referenced in a separate array too. Therefore changing selection with arrow-keys would be possible with simple index calculations.
Further Notes: I assumed that the user-control that is to be created is named MyThumbnailControl, just a random name to refer to that control. When you create a new user-control, the wizard generates a class for you with your desired name (e.g., MyThumbnailControl), you can define a property inside it named IsSelected and implement its getter and setter. See this for a tutorial. After defining the user-control you can instantiate instances from its corresponding class. Also by global reference, I meant a variable at the form (or any parent control) level. To keep it simple we can add a reference of the selected thumbnail in the form that is going to hold the grid and thumbnails: MyThumbnailControl selectedThumb = null; or something like this in the body of the form.
Here is something, I just fixed you.
Create a C# project name CreateImageList and in the Form1 add the following 5 controls with their default name i.e. Panel1, PictureBox1, Label1, Button1, Button2:
How it works:
When the page load it create an imageList objects and load all .jpg images from a folder you provide
ImageList Images are set into the PictureBox control and when user clicks "Button1" the picturebox shows next image in ImageList and when user clicks "Button2" the PictureBox shows previous image from ImageList.
The Label1 shows the currentImage counter from the ImageList Arrage. If you want to write something specific, you can create an array of text and sync with your image counter.
When user click on PictureBox the a border is create to show Picture highlighted
When user Double Click on PictureBox a MessageBox appears shows DoubleClick event.
Now, you can use the following code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
namespace CreateImageList
{
public partial class Form1 : Form
{
private int currentImage = 0;
protected Graphics myGraphics;
ImageList iPicList = new ImageList();
public Form1()
{
InitializeComponent();
DirectoryInfo dirImages = new DirectoryInfo("C:\\2012");
iPicList.ImageSize = new Size(255, 255);
iPicList.TransparentColor = Color.White;
myGraphics = Graphics.FromHwnd(panel1.Handle);
foreach (FileInfo file in dirImages.GetFiles())
{
if (file.Extension == ".jpg")
{
Image myImage = Image.FromFile(file.FullName);
iPicList.Images.Add(myImage);
}
}
if (iPicList.Images.Empty != true)
{
panel1.Refresh();
currentImage = 0;
// Draw the image in the panel.
iPicList.Draw(myGraphics, 1, 1, currentImage);
// Show the image in the PictureBox.
pictureBox1.Image = iPicList.Images[currentImage];
label1.Text = "Image #" + currentImage;
}
}
private void showImage(int imgIndex)
{
// Draw the image in the panel.
iPicList.Draw(myGraphics, 1, 1, currentImage);
// Show the image in the PictureBox.
pictureBox1.Image = iPicList.Images[currentImage];
label1.Text = "image #" + currentImage;
panel1.Refresh();
}
private void button1_Click(object sender, EventArgs e)
{
if (iPicList.Images.Count - 1 > currentImage)
{
currentImage++;
}
else
{
currentImage = 0;
}
showImage(currentImage);
}
private void button2_Click(object sender, EventArgs e)
{
if (iPicList.Images.Count - 1 >= currentImage)
{
if (currentImage == 0)
currentImage = iPicList.Images.Count-1;
else
currentImage--;
}
else
{
currentImage = iPicList.Images.Count;
}
showImage(currentImage);
}
private void pictureBox1_DoubleClick(object sender, EventArgs e)
{
MessageBox.Show("Picture Box Double clicked");
}
private void pictureBox1_Click(object sender, EventArgs e)
{
panel1.Refresh();
myGraphics.DrawRectangle(Pens.Black, 0, 0, iPicList.Images[currentImage].Width + 1, iPicList.Images[currentImage].Height + 1);
pictureBox1.Image = iPicList.Images[currentImage];
}
}
}
The changes you need are:
Change the Following folder to a place where you have lots of jpg:
DirectoryInfo dirImages = new DirectoryInfo("C:\\2012");
Also if you are dealing with other kind of images, make change here:
if (file.Extension == ".jpg") // Change it to your image type.
If you don't want to use the the buttons to go up and down, you have several other options to host PictureBox control in scrollable Panel or list or something else.