I've searched around for an alternative way of drawing selection indicators for visual objects (like selected edges, lines etc.) without the use of ControlPaint.DrawReversibleFrame and related XOR methods. The reasons are unwanted XOR-ing "artifacts", reversibility not applying to bitmaps, no control of the actual visual look and slowness.
On the other hand I want to avoid having to repaint the whole scene (map actually) if a user decides he wants to deselect an object or two, because the repaint could be quite expensive.
So the only alternative I can see is implementing some basic drawing logic directly on a Bitmap, but with storing the previous contents of the pixels before they change. Then (in theory) I would be able to reapply old contents of, say, an selected edge rectangle if the user chooses to deselect that edge.
My question is whether you think this is a good idea or do you see some other alternatives to my problem (within the GDI+)?
Thanks in advance
If the selection indicator is just drawn on the top of the unselected object, you can use two bitmaps, draw all the unselected objects on the background one and the selection indicators on the other, and paint them both on screen.
Else, you can do the same, except that you render the selected objects instead of just indicators.
Only store the rectangles "of interest" in an off screen buffer. And repaint when the focus is lost. . . Or if you can redraw just the portion as it appears normally based on in memory data you should be fine. Otherwise it seems that you have the gist of it.
Related
I have a problem with screen flickering. I read some other topics on this case, but there are solutions that didn't work for me, I think that's because I don't know what exactly causes the problem.
My screen is has a large number of controls, maybe this is what causes the problem. I'll try to describe it as best, as I can.
First of all, I am using WinForms.
I am making a video game, so the screen should be maximized all the time.
To allow stretching all the controls I am using TablePanels, one large that is docked to fill the whole form and a few smaller that also dock fill the large Table cells. In smaller cells of those tables, Buttons are docked fill.
To show the background drawn buttons, I made control buttons completely transparent. It needs to stay that way.
The screen flickers white at positions of TableLayoutPanels borders.
The screen flickers when a mouse enters the position of a Button, any Button, no matter where it is located.
For now, only one element changes actively during gameplay - a Label. When mouse enters the field of button, this label shows what this button does. For example if I enter the area of "Use" button, the label displays the word "USE".
I haven't tried that yet, but I must implement, that some images of button will change or become transparent, or lose transparency during game-play. Like there could be one image for closed cupboard, but when player opens it, another image of open cupboard appears. I think I know how to do it, all I want is to prevent flickering.
If you suggest using some code (and I expect it will be needed), please specify where I should put it.
It seems problem was solved.
I'll answer my question myself, in case someone else needs it.
The problem was caused by one of labels, although I can't guess why.
I am using a number of TableLayoutPanels, one of them fills the whole form. It has a number of rows, each of them is also a TableLayoutPanel, or just a Panel.
Flickering appeared when I tried to put a label inside main TableLayoutPanel by its own, and not in a sub panel. When I put a Panel inside main Table, and label inside it, the majority of flickering was gone.
To remove it completely, I used both recommendations just in case:
1) DoubleBuffering: Here (answer from Fabjan)
2) Article also recommended by Fabian
After that, only a few minor glitches remained. I did a few tests and it seems that the last glitches happened when mouse left the screen, then returned back inside. My game screen is maximized, so it took some time to check. To fix it, I used an easy command:
"Cursor.Clip = this.Bounds;" on FormLoad
I learned it from another question from this site: Here
Unfortunately, I didn't understand, why misplaced label was behind flickering, but since the problem was solved, I decided to write it here, in case someone else needs it.
Using VS2013, C#.NET 4.5, and WinForms. Migrating to WPF is not an option at this point.
The standard checkbox control handles 2-state and 3-state modes, but I need a 4-state checkbox. I can't find a 4-state checkbox library on the net anywhere, so I'm assuming I'll have to make one (if y'all know of one, that'd be great).
I have a set of four PNGs as draft images of the checkbox appearance, and I have played around with just painting those on a button and having the button_click event cycle through which image is displayed and update the data value. This doesn't seem to scale the image with the button well, though, and it feels kludgy to load static bitmaps instead of vector drawing the images so they're always to scale.
Is there a way to inherit from the checkbox control itself and add a fourth state?
If so, where do I go to override how the states are drawn? I need to do it "correctly" so that if the form is Scaled, the checkbox doesn't end up looking all bitmap-nasty.
I'm not even sure what keywords to use to search for how to do the actual drawing.
Background:
I'd generally consider this to be a nasty UI choice, but I'm making a program that saves, loads, and displays a "World of Darkness" character sheet of any arbitrary system, and the WoD games use a 4-state injury that's represented on the sheet by an empty box, a box with one slash across it, a box with an X across it, or a box with a 4-stroke asterix across it (optionally, a filled box).
For the moment I'm going with matching the original with high fidelity; later, as an option, I'll let the user switch to radio buttons to support my own preference.
This is my first real exploration of GUI programming beyond the basics, so I'm not sure quite how to proceed.
EDIT: I'm delving into a UserControl now, and my own draw methods. What fun. Found an MSDN tutorial on User-Drawn Controls, seems like a good starting place.
I have a set of custom controls and a list of geometric objects that I need to draw on the same handle.
I override the OnPaint procedure, put the base.OnPaint(e) in the first line and commence with the drawing of the geometric objects (via e.Graphics.DrawLine etc.).
Those are in a locked list and decay after a while.
Also the customized controls can move around the window.
Now this is almost working as intended except for this fun fact:
The geometric shapes appear only after a control is moved along/above their layouts.
I was able to reproduce this in a small environment: PASTEBIN
I tried flushing the graphics object; save/restore; changing Clip.
Nothing seemed to work.
I am guessing that regions only get invalidated and repainted once a control is present. But how can I force them to be drawn anyways?
Control.Invalidate will tell the framework that the control needs to be redrawn. It does this automatically to redraw controls after, for example, the mouse has obscured part of it, but it will only redraw a the small section that the mouse covered (hence why you end up with a "(re)painting with the mouse" effect. Also moving a window will force it to redraw, as does covering it with another window and then moving that window away again.
But if you are doing a bunch of custom painting, you need to let it know that the control needs to be redrawn by calling Invalidate yourself.
I need to load an image in a WPF window, an be able to read and modify individual pixels (in an efficient way), zoom the image (and scroll it), get the value RGB/grayscale of the pixel under the cursor, select areas (I guess knowing the cursor position and being able to modify pixels I could draw myself the square which represents the selected area)...
What is the best combination of WPF controls and classes to accomplish this?
I've been trying to do it loading a System.Windows.Media.Imaging.BitmapImage and putting it into a System.Windows.Controls.Image, but it's taking much longer than I expected.
Thank you very much
I once used this WPF Interactive Image Cropping Control. Go check it out, it should at the very least give you a good place to start. Oh, and welcome to Stackoverflow. :)
As my first WPF project, I am attempting to build an application to play a card game similar to Magic the Gathering. It is not clear to me how to lay out the main play area. You can see some examples that are similar to what I am attempting by looking at example 1 or example 2. The chat/info areas on the right would be separate user controls.
The cards must maintain their aspect ratios, and each play area would start with 10 columns and two rows of cards. As more cards are played, the number of columns and/or rows may change. Each player area may have a different number of columns and/or rows. Cards may overlap, and may be placed sideways (tapped). Cards in all areas should be the same size (although they may be cropped in some areas). Cards do not need to lie exactly on the grid (they do not necessarily snap-to-grid).
When the user hovers the mouse over a card, it should expand to a significantly larger size using an animation. A card in one player area may overflow into the other player's area when expanded (but only as long as the mouse hovers).
Given these requirements, I am tempted to use one large user control derived from Canvas with image objects for each card (along with other shapes to delineate the areas). This implies that I will be doing a lot of work during the OnRenderSizeChanged event to position the child items within the canvas (manual layout).
Using a grid does not seem feasible to me, due to the free-form placement and overlap.
Decomposing the play area into smaller user controls would leverage the WPF layout capabilities, but it seems like decomposition would prevent the cards from expanding into adjacent user controls during the mouse-over, so that doesn't seem feasible either.
Is there a better alternative to one large canvas-based control? It seems wrong to be doing manual layout in WPF, but I cannot see an alternative.
This sounds like a great scenario for Composite Application ala Prism. It provides solid framework for implementing regions, modules, sending message between modules etc... From looking at your screen captures, developing a shell with different regions and dropping modules into them would probably greatly benefit your layout. As for the cards themselves, perhaps they could be modules as well?
Check out:
http://msdn.microsoft.com/en-us/library/ff649780.aspx
Particualy good examples come with the download package including a stock market like application and event aggregator example.
You said:
Decomposing the play area into smaller user controls would leverage the WPF layout capabilities, but it seems like decomposition would prevent the cards from expanding into adjacent user controls during the mouse-over, so that doesn't seem feasible either.
But this is not correct. Decomposition is absolutely the right approach to take, and this would not prevent the cards from expanding into adjacent user controls. The reason being that you can use a RenderTransform rather than a LayoutTransform. See this example, by Charles Petzold, or this article, to visualize the difference. Because a RenderTransform is applied after the layout has already occurred, your cards would be able to expand outside their bounds.
Given that decomposition is the right approach, I would arrange your various card collections into a Grid, with each collection being an ItemsControl. The ItemsControl should bind its ItemsSource property to some collection, and then you can provide a custom ItemTemplate that would display the image and any other information. I would be hesitant to use a Canvas, as this would restrict you to hard-coding the positions for the cards (which is a very WinForms-like solution for a problem that can be far more elegantly solved). Take advantage of WPF's fantastic layout engine and use nested grids and items controls to create a dynamic layout. This will ensure that your game board looks good at any resolution and when stretched to various sizes.
I recommend you take a look at this guys project . In java I know but if I was to go the route of building a card game. That would be what I would go off of.
A lot of canvases inside of a grid could help you here, the canvas will allow the content to render outside of its bounds, as long as you turn ClipToBounds to false, and you will be given much more control over exact placement of the cards than with other schemes. You will also get the powerful functionality of a grid control, allowing you to add and remove columns and rows as needed (though you will also have to dynamically add and remove canvasses, though this isn't too difficult.
If you're worried about the contents of your "Card" moving around when the box is rescaled, surround it in a viewbox. It will manage all your scaling for you, and ensures your card uses as much real estate as it can get. Alternatively you could use a RenderTransform, but a lot of these might slow your program down (Experts: does the viewbox operate using RenderTransforms? If so this point is moot)
To ensure the cards maintain their aspect ratios make sure each Image's Stretch attribute is set to "Uniform", making them all keep the same size could be done by designating a master card, and binding heights and widths of all subsequent cards to this original card, though that is a little messy and doesn't allow the cards to expand. Another solution is to set a single size for each card manually, animating this when you want to expand or shrink.