Drawing ListViewItem exceed VisibleClipBounds - c#

I'm trying to manually draw ListViewItems on a Custom UserControl. The control itself is a wrapper around a ListView stored as a private member on the class.
There is a DrawListViewItemEventHandler attached to allow manual drawing for these items, and for the most part this seems to work. The problem I have is where the text for the ListViewItem (in large image mode) is long.
I'm drawing a bounding rectangle around the ListViewItem with various themes, and I then measure the size of the text using Graphics.MeasureString() and manually draw the text. However what I'm finding is that the vertical drawing is cropping at 2.5 lines of text, because the caption is falling outside of the VisibleClipBounds of the graphics context I have been passed.
It seems a bit of a strange but I'm not sure why such a thing should happen and can't figure out how to get around the problem.

You could use Tile view and TileSize to give yourself enough space to draw your text.
The ListView can't guarantee to draw all its text: the text could be huge.

Related

Autoscroll panel with graphics drawn on it

I have a WinForms app, which has a large panel, which I am drawing on to. Basically, I implemented a scrollbar mechanism, which can imitate a zoom behavior on my drawing. Now I want to do something more.
I thought about adding a possibility to not zoom my drawing if it doesn't fit on the panel, but just use a scroll (vertical or horizontal) to see the full picture. So it looks like this:
Zoom is set to 1: (drawing is too big, there are supposed to be 4 circles)
I zoom back, and there they are, but really, really small:
And I want to have a possibility to just scroll the panel (f.e. in this situation horizontally), to see the whole drawing without having to shrink those drawings.
P.S I searched through SO, and I only found answers suggesting using PictureBox instead of Panel and I'm not sure I want to do that

Transparency over multiple pictureBoxes

I have an array of picture boxes that are arranged in a square. I want to put a larger, mostly transparent picture box over the top. But when I do it covers the other picture boxes and just draws the background of the form.
Is there a way to get it to have all the other picture boxes show where it is transparent?
Transparency in WinForms isn't great. Some controls have transparency support, others don't. Some controls can be subclassed to enable this (by calling Control.SetStyle() with the SupportsTransparency flag). I believe this can be done with PictureBox.
However, transparency in all WinForms controls works by having the transparent control call its parent control to draw the background before the child control draws. This means that you cannot have two sibling controls and expect transparency on one to show through to the other. Sorry!
All that said, it would be possible to code your own workaround to support this. It would involve subclassing PictureBox and clever coding in the OnPaint override to locate sibling controls and manually trigger painting of them into in-memory bitmaps. Lots of gotchas with this approach.
Try WPF!
Here's a tip to get the desired result:
Create multiple copies of your top image.
Add each copy to the Controls of each picture box it should cover.
Adjust location of each copy according to the offset of each picture box to be covered.
So you will see every copy of your big image covering each picture box as if they were a single image.

How to display images on top of each other using C# (Forms or WPF)?

I need to display images on top of each other. This can either be a composite\layered image or separate images. This will typically be a larger image with smaller images on top. With the composite\layered approach the smaller images would each need to be a separate (and accessible) layer. With the separate images approach the smaller images are on top with a transparent background. With either approach the smaller images must be accessible i.e. can be moved (dragged) or deleted. The app needs to display these images together (as if it was one image) and keep track of the coordinates (position) of the smaller images.
The current (proof-of-concept) solution has a PictureBox control that displays the large image and a treeview. Nodes are dragged from the treeview to the picture box and rendered using the graphics DrawString or DrawImage methods – these draw the smaller images. The problem is that once the smaller image is drawn I cannot get back to it as a separate graphics object. The picture box “sees” it as part of the current image.
I need to do this in C# (WinForms or WPF). And the image type must be a common and open format i.e. not proprietary. Preferably no 3rd party controls.
Any suggestions\guidance?
WPF would be the technology of my choice for this project.
Drag & Drop way nicer, without flickering, better concept
Rendering directly on HW, way smoother for image manipulation
General idea of the implementation:
MVVM pattern
ViewModel holding your layer information
ItemsControl bound to the collection of Small overlay Images holding a DataTemplate which visualizes the images thour custom UserControl based on a Thumb (for drag & drop functionality) displayes the small images on top.
Easy to add functionality to drag, edit, hide each small image seperately.
The problem is that once the smaller image is drawn I cannot get back
to it as a separate graphics object. The picture box “sees” it as part
of the current image.
That behaviour is perfectly normal. GDI drawing does not work with objects. To do what you are asking, you need to track any event that can cause a change in the final image and when such an event occur, you need to draw the whole image from the begining, including the first image (assigning the background image, I guess).
May be create picture box per image. The transparent background will give the effect of single image.

WPF: How to find space available for Canvas?

I'm using WPF shapes to create Hexagons (for a game map) on a Canvas. After some playing around with ScrollViewer, I've decided to implement the scrolling and zoom of the map myself rather than using WPF functionality, just using WPF to get the events for mouse wheel, arrow keys etc. I'm placing the (Hex Map) Canvas as the last child inside a Dock Panel so it will get all the available remaining space. The Dock Panel will be set to be the content of the Main Window. But I want to find out how big the Canvas can be before I put any Children on the Canvas so that I can centre the screen over the Hex I want and only add the Shapes (Hexs) that can actually be seen. When zoomed out, a long way I will remove Polygons altogether and use another method of rendering and when zoomed in a long way I will add more details.
Is there any neat way of getting the available space? The only way that I can think of that will hopefully work is to get the current dimensions of the windows and subtract the dimensions of the outer elements of the Dock Panel, but that feels rather messy.
You may use the ActualWidth and ActualHeight properties of Canvas to determine size available to it. Be sure that HorizontalAlignment and VerticalAlignment are set to Stretch.

Display Individual Pixels in WPF

I have an application that needs to highlight individual pixels on an image. I don't want to edit the image, I just want to temporarily display red dots on top of certain pixels in the image. So far I have been using a Canvas to draw a whole lot of really small rectangles to highlight those pixels, but that has performance issues, and I was wanting to know if there was a better way to do it.
You can place another image layer over the original one with a transparent background and simply put red pixels on it.

Categories