WinForms: ListView's BackgroundImage positioning - c#

I've put a BackgroundImage on my ListView in one of my windows forms.
Everything works as expected. But now I'd only like to position this image inside the ListView.
Like in CSS: background-position: top right; Would stick the image at the top right corner of the element.
Is there any way of doing so with a windows form?
Thanks a lot :)

It is possible, so yes, you can. Put on the resize or anywhere else if you don't resize listview
(need some optimize I guess, dont know)
Bitmap bmp = new Bitmap(listView1.Width, listView1.Height);
using (Graphics g = Graphics.FromImage(bmp))
{
SolidBrush br1 = new SolidBrush(Color.White);
g.FillRectangle(br1, 0, 0, listView1.Width, listView1.Height);
g.DrawImage(Image, listView1.Width - Image.Width, listView1.Height - pictureBox1.Image.Height);
}
listView1.BackgroundImage = bmp;

The short answer is: you can't.
This blog documents why LVM_SETBKIMAGE and intercepting WM_ERASEBKGROUND do not work with .NET ListViews.
The solution I found for this problem -- and which is used in the ObjectListView project -- is to use the low-level custom draw facilities of the native ListView control. It was complicated to implement, but is (now) easy to use.

the only way I know is to inherit from ListView and override the OnPaintBackground methode and draw the Image with Graphics.DrawImage() on your own. But you have to calculate the position on your own ;) You can also add a costum property for the aligment of the type System.Drawing.ContentAlignment.

otherwise you can tile the image , but it wont be stuck in one place .
listView1.BackgroundImageTiled = true;

Related

Why Isn't ControlPaint.DrawGrid Function not Displaying Anything to a PictureBox

I want to make a graph paper grid and set the drawing to the image of a picture box. Now I might even be using the wrong thing for drawing a graph paper grid but I have asked around and some people said that the DrawGrid method would work. None of the code below is returning any errors, but when I run the button1_Click method, it doesn't display anything to the picturebox.
private void button1_Click(object sender, EventArgs e)
{
button2.Visible = true;
Bitmap bmp = new Bitmap(pictureBox1.ClientSize.Width, pictureBox1.ClientSize.Height);
Size yourGridspacing = new Size((int)numericUpDown1.Value, (int)numericUpDown2.Value);
using (Graphics G = Graphics.FromImage(bmp))
{
ControlPaint.DrawGrid(G, new Rectangle(Point.Empty, bmp.Size), yourGridspacing , Color.Black);
}
pictureBox1.Image = bmp;
}
Any idea what the problem might be?
Your PictureBox probably has a White Background.. If so, please tell the ControlPaint.DrawGrid method so..:
ControlPaint.DrawGrid(G, new Rectangle(Point.Empty, bmp.Size),
yourGridspacing , Color.White);
The param doesn't control the color of the dots; it is supposed to help find a Color that will contrast. So maybe the best way to write it will be:
ControlPaint.DrawGrid(G, new Rectangle(Point.Empty, bmp.Size),
yourGridspacing, pictureBox1.BackColor);
This will work for all colors except Color.Transparent.. (in which case the Color of the control below will decide if the dots are visible..)
You may wonder, why such a roundabout way is chosen? Well, the method DrawGrid is not really meant as a normal drawing method, like the ones in Graphics. It is one of several methods that are meant to construct a robust display of Windows controls like Button or CheckBox.. Now, the Background over which the Grid is drawn need not have only one Color; it could be an Image or a Gradient and it could change..
You are supposed to pick a typical color to represent that background. The system will then choose a Color with good contrast for the dots.
For a way to control the grid's color see the last option in my other answer!

Rectangle Selection Like Tool MS Paint C#

I have been working on creating a program similar to MS Paint. I have several of the features it has down but the one which is currently giving me trouble is the rectangular selection tool. My program currently draws everything on the panel and saves it all in an ArrayList so each shape can be redrawn in Paint().
Like MS paint I would like the user to be able to select a section of the drawing on the panel and either copy it, move it, re-size it, or even delete it. I was thinking about having the user draw a rectangle & saving the information for it. Then taking that information for the rectangle, passing them to create a new Bitmap. I would then paint a new rectangle in the background color to give the appearance that the selected area was "removed" when the selected portion is moved. It sounded okay until I realized that I couldn't use the Graphics.FromImage() on the PaintEventArgs variable passed to Paint() which made my idea useless. Not sure if that makes sense so my apologies if it's a confusing mess.
I've been searching the internet for some assistance and I haven't found much to help so either this is very easy to do, very difficult, or "rectangle selection tool" is not the proper term. Any help or pointers would be greatly appreciated!!! Thank you for your time! :)
I understand that you actually have the Rectangle and now would like to copy an area from your painted Panel.
This is possible, assuming you have, as you should, placed all the painting in the Paint event of the Panel.
Then you can, use DrawToBitmap to ask the Panel to draw itself onto a new Bitmap; from there you can DrawImage the Rectangle onto your Panel.
Note: For this to integrate with your list of 'Paint-Actions' you will have to either now store that Bitmap or store the Rectangle and redo the whole operation.
using (Graphics G = panelCanvas.CreateGraphics() )
{
Rectangle R0 = new Rectangle(22,22,55,55); // your Rectangle!
using (Bitmap bmp = new
Bitmap(panelCanvas.ClientSize.Width, panelCanvas.ClientSize.Height))
{ panelCanvas.DrawToBitmap(bmp, panelCanvas.ClientRectangle);
G.DrawImage(bmp, 111f, 111f, R0, GraphicsUnit.Pixel);
}
}
Aside: Please do replace the ArrayList, which is depracated by the new List<T>, e.g. a List<PaintAction> or whatever name your class has!
If you simply want to extract a rectanglular area from the Panel Control you can use thsi function:
public Bitmap getAreaFrom(Control ctl, Rectangle area)
{
Bitmap bmp2 = new Bitmap(area.Width, area.Height);
using (Graphics G = ctl.CreateGraphics())
using (Bitmap bmp = new Bitmap(ctl.ClientSize.Width, ctl.ClientSize.Height))
{
ctl.DrawToBitmap(bmp, ctl.ClientRectangle);
using (Graphics G2 = Graphics.FromImage(bmp2))
G2.DrawImage(bmp, 0f, 0f, area, GraphicsUnit.Pixel);
}
return bmp2;
}

Visual C# - Rendering images from form?

I have a fun application written in Visual Studio (C#), and I'm wondering - What I do is I draw panels in certain ways on the form - if it's possible to render the form, without taking a screenshot?
Thanks
If by "taking a screenshot" you mean "sending PrtSc", then there's a better way, using System.Drawing.Graphics.CopyFromScreen:
using(Bitmap b = new Bitmap(this.ClientSize.Width, this.ClientSize.Height)) {
using(Graphics g = Graphics.FromImage(b)) {
g.CopyFromScreen(this.PointToClient(Point.Empty), Point.Empty, this.ClientSize);
}
// Your form is now rendered into b.
}
If you want to include the border, just use Size instead of ClientSize, and this.Location instead of this.PointToClient(Point.Empty).
Alternatively, you can use this.DrawToBitmap:
using(Bitmap b = new Bitmap(this.Width, this.Height)) {
this.DrawToBitmap(b, new Rectangle(0, 0, this.Width, this.Height));
// Your form is now rendered into b.
}
This will work even if your form doesn't have focus. However, it will draw the border and it will draw it in Windows Basic style if Aero is active.
No, it's not possible to capture the visual of the form as an image other than what is offered by some sort of screenshotting library (if that's what you're asking).

Efficient Zoom At C#

To zoom images in and out, there is a possible way to resize the pictureBox and showing image in strechmode. Although I can not use it efficiently becauce in general over 8x it gives storage error [think that a pictureBox has the Size(32k, 32k) it needs over 1GB memory !
Is there a special method, or should I zoom only the seen part of the image by using ImageClone ?
Update:
Here is the project at first try to zoom at the project [impossible, storage error] than delete the 41. line in form.cs :
pictureBox1.Image = youPicture;
After deleting this line, the program will work, please move the zoomed image.
Here is the link: http://rapidshare.com/files/265835370/zoomMatrix.rar.html
By using the matrix object and the transform property of your graphics object:
using(Graphics g = this.CreateGraphics())
{
using(Bitmap youPicture = new Bitmap(yourPictureFile))
{
g.DrawImage(youPicture, 0, 0, 300, 100); //set the desired size
//Now you need to create a matrix object to apply transformation on your graphic
Matrix mat = new Matrix();
mat.Scale(1.5f, 1.5f, MatrixOrder.Append); //zoom to 150%
g.Transform = mat;
g.DrawImage(youPicture, new Rectangle(...), 0, 0, youPicture.Width,
youPicture.Height, GraphicsUnit.Pixel) ;
}
}
I personally would just zoom the visible part as the rest is hidden anyway (and thus no use)
See this answer to an earlier question. You definitely don't want to zoom by making the image huge and showing only part of it - you'll run into the memory problem that you've already encountered. Also, the stretch mode of a picture box doesn't use high-quality interpolation, so the result will look pretty crappy.
In the answer I linked here, I included a link to a C# project that shows you how to do this kind of zooming.
Update: here is a direct link to the downloadable project.

.NET set image display size

I am using some custom controls one of which is a tooltip controller that can display images, so I am using th ebelow code to instantiate it:
Image newImage = Image.FromFile(imagePath);
e.ToolTipImage = newImage;
obviously could inline it but just testing at the moment. The trouble is the image is sometimes the wrong size, is there a way to set the display size. The only way I can currently see is editing the image using GDI+ or something like that. Seems like a lot of extra processing when I am only wanting to adjust display size not affect the actual image.
Once you have an image object loaded from its source, the Height and Width (and Size, and all ancillary properties) are read-only. Therefore, you are stuck with GDI+ methods for resizing it in RAM and then displaying it accordingly.
There are a lot of approaches you can take, but if you were to encapsulate that out to a library which you could reuse should this problem occur again, you'll be set to go. This isn't exactly optimized (IE, may have some bugs), but should give you an idea of how to approach it:
Image newImage = Image.FromFile(myFilePath);
Size outputSize = new Size(200, 200);
Bitmap backgroundBitmap = new Bitmap(outputSize.Width, outputSize.Height);
using (Bitmap tempBitmap = new Bitmap(newImage))
{
using (Graphics g = Graphics.FromImage(backgroundBitmap))
{
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// Get the set of points that determine our rectangle for resizing.
Point[] corners = {
new Point(0, 0),
new Point(backgroundBitmap.Width, 0),
new Point(0, backgroundBitmap.Height)
};
g.DrawImage(tempBitmap, corners);
}
}
this.BackgroundImage = backgroundBitmap;
I did test this, and it worked. (It created a 200x200 resized version of one of my desktop wallpapers, then set that as the background image of the main form in a scratch WinForms project. You'll need using statements for System.Drawing and System.Drawing.Drawing2D.
In Winforms, if you contain the image inside a PictureBox control, the PictureBox control can be set to zoom to a particular height/width, and the image should conform.
At least that's what happened in my Head First C# book when I did the exercise.

Categories

Resources