I've looked through many topics here, and googled for the information, but I haven't found anything relating to my question.
What I want to do is have it so when a user starts the application, the main window (not an MDI) opens with four imageboxes, each showing an image of the form that would open when they click on it. Once the selected form is open, and changes are made, if they click to minimize/close the form, it will (seemingly) minimize into the imagebox showing a real-time image of what the form looks like in a thumbnail view.
My question is, how do I make a form into an image so I can use the image as a thumbnail in an imagebox?
Also... Can someone point me in the direction of some resources that will help me figure out how to animate the "minimizing" into the imagebox?
I'm not asking anyone to do my work for me, because I'd like to learn it myself, but I'm kinda stuck.
Lastly, I'm not sure what's involved in this, so I don't know what tags to put for this post. I'll add tags as I figure it out so others can find this information.
EDIT: Sorry, it is in WPF. Wasn't sure it would be any different. I'm still not particularly experienced in WPF.
You can use the VisualBrush, here is a quick example of a button with a background set to a downscaled version of a stackpanel.
Edit: though this solution works to copy stuff that is on the screen, when the stuff on screen is hidden or removed, so will the VisualBrush. In order to persist the image, it is necessary to render the control to a bitmap. This can be done with the RenderTargetBitMap
I'm going to assume you want actual separate windows that can be dragged and dropped independently around your screen among other applications' windows. (If this assumption is incorrect and a MDI-like interface is better for you, take a look at Rob's answer.)
I would implement an Expander subclass that accepts a Window and:
It might be named "WindowExpander" and would have its Content property set to the actual Window object to be shown when the Expander is expanded. For example it could be used in one of these ways, depending on how your Windows are defined:
The implementation of WindowExpander would be a ToggleButton containing a ViewBox that displayed the the thumbnail, like this:
I'm thinking you would probably want to implement WindowExpander something like this:
The above code omits the steps to construct the animation. It also has not been tested - it was just written quickly off the top of my head. I hope it works for you.
How it works: IsExpanded controls the Window's visibility, except that when IsExpanded changes the storyboard temporarily forces the window to stay visible long enough for the animation run. At any given moment either the Window or the ContentPresenter in the template contains the window's content. You might say that whenever the expander is not expanded (no window), the Content is "stolen" from the window for use within the WindowExpander. This is done by the SwapContent method. It puts the Rectangle painted with the VisualBrush into the Window and the Window's actual content into the Header, which is the thumbnail shown on the ToggleButton.
This technique works around the fact that VisualBrush doesn't work on an invisible Visual because the "Content" visual is actually always visible - it is always a child of either the Window or of the ContentPresenter inside the ViewBox.
Because a VisualBrush is used, the thumbnail always gives a live preview.
One caveat: Don't set a DataContext or create resources at the Window level. If you do, when your content is "stolen" it will not have the right DataContext or resources so it won't look right. My recommendation would be to use a UserControl instead of a Window for each form, and have your main form wrap it in a Window as illustrated here:
If you're beginning with WPF, then what you're planning to do will likely require that you either learn Blend in order to define the conditions and animations, or dive deep into the animation system in order to understand it and hand-code the XAML.
At a high level, I imagine you could approach this by defining each of your four "forms" as UserControls or ContentPresenters, perhaps with a Border around them.
Then, when the "form" is in an inactive state, use the
LayoutTransform
orRenderTransform
property along with other positioning properties to position and shrink it. Once your brain is accustomed to Blend it's actually pretty easy to define this using the "States" and "Triggers".To add a behavior to grow the minimized form, handle the "PreviewMouseDown" event and in the handler, test for the state of the form.
I found the "Learn Blend in 5 Days" videos useful for this, but I'll confess to sharing your confusion; there is no unified place that I've found which teaches XAML and WPF in a systematic way, without simply enrolling in a third-party training class or calling in a mentor-consultant. It doesn't help that at this time, the fifth day of the training is "Coming Soon", or that the entire thing is keyed to Silverlight rather than WPF.
But, it's a start; The "Learn Blend" videos are found here:
http://www.microsoft.com/expression/resources/blendtraining/
You'll also see a link to something called ".toolbox", which I haven't yet tried.