Screen and print layout for a XAML window - c#

I have a rather complex WPF XAML window, which represents a printed form.
Mainly, on top, there is a Canvas at size of an A4 page. The children of the canvas are a lot of nested StackPanels, and then again lots of labels, textblocks, textboxes, labels, check boxes, drop downs, etc.
I print the window as follows:
PrintDialog dlg = new System.Windows.Controls.PrintDialog();
if (dlg.ShowDialog() == true)
{
dlg.PrintVisual(this.PageCanvas, "Document");
}
Now, during print, I want that colors and borders of textboxes disappear. Even more, I'd even like to replace some TEXTBOXES and CHECKBOXES with TEXTBLOCKS.
a) Are there pre-built methods for switching between "screen mode" and "print mode"?
b) Or, otherwise, can I exchange certain controls at run time with textblocks ?
I want to avoid to create two variants of the same form (one for screen, one for print), because this would double all future maintenance work.

well I'm thinking probably the best thing to do would be to create another form and design it in the way u want then when u click the print button print that form... don't forget to databind the objects.... easiest method would be to use datastore.

Just for documentation: As a temporary solution, I found a way to replace a control in some panel at runtime like this:
this.somepanel.Children.Remove(this.sometextbox);
TextBlock n=new TextBlock();
n.Text = "...";
n.TextAlignment = TextAlignment.Right;
this.somepanel.Children.Add(n);
This is a solution that works; however, I'm quite sure that there are better solutions, which make better use of the whole WPF concept.
However, for the time being, I do it like this for a 1st version. For a 2nd version, I will go more in depth of WPF, and possibly post an additional answer or article.

Related

Developing multi tab windows

let's say I want to make program settings menu like:
Many tab options that change the layout of the rest of the window
My program is in C# and I'm making it in Visual Studio
I tried to do it 2 ways:
Make the window super large with all possible layouts in the Form designer and then just resizing it to fit one of them at the time but this method works for like 4 tabs when you can fit them all at 1 screen. If it's large you have to work with slide bars and that's really impractical, laggy and for many tabs you even have to search them
Not using Form designer at all and hand write all the declarations, positions, sizes, colors etc. But like this it takes pretty a while even just to set up 1 button and there is no way I can fast see how it looks like
So the question is: Is there a magic way I don't know about to do this? And how is this made professionally?
Simple solution for small number of views
You can use a TextBox and ListView docked in a Panel docked left.
And a ControlTab docked fill in a panel named for example PanelMain docked fill at right with visible at false.
You will create any tabpage as option. In each tabpage you will put a panel docked fill and dedicated content in. On the listview item click event or itemchange, you will set the tabpage panel parent to PanelMain.
The little problem can be about spacing and the code file can be large (regions can be used).
Advanced solution more clean for several views
You can use the standard multipage pattern with one form per option/view, and do the same thing as exposed previously.
You create one form per view and put a panel docked fill embedding controls.
When the user click on the menu, you set the form main panel parent to the option form or the main panel of the options form.
I hope I haven't written too badly in unverified English.
Feel free to open any new question centered on any atomic and code problem on this subject.

Scale WindowsForm

Basically, I want everything (Controls etc) to scale with the WindowsForm when resizing it by dragging, so that the user can determine the size of the UI himself.
The picture is not perfect, but I hope it explains it:
The easiest way to do this would be to use a (Flow/Table)LayoutPanel and the appropriate Anchor/Drop properties, but I feel like that restricts my design, which currently looks like this:
My idea was to scale all the components when Resize() is called:
foreach(Control c in Controls){
c.Scale(scaleFactor);
}
My problems are: Locations aren't set properly and the rounding needed to determine the 'scaleFactor' leads to inconsistencies.
Is there a clean way to do all this? Do I have to use LayoutPanels to get a clean way?
Are you sure that you want to zoom those text boxes and labels, too? Text boxes have a fairly standard height, for example. What do you expect if the window is so small that the text is too large for the buttons/text boxes, etc.?
The typical resizing logic of the contents of a resizable window is a little bit different. I would rather create a borderless panel for the groupboxes and stack/dock everything like this:
If I resize this window, that will look like this:
Btw, I do not like if buttons are resized like this. I would use only Anchor = Left, Right for them so they would preserve their height. And do not forget to set a proper MinimumSize for the form.
Simplest and cleanest way is use layout panles.
It's hard to code location of controls which depends of previous control's location and size (expect case when you know order of controls).
In WPF everything are on ContentControl which is layout panel. Location of control is calculated automatically.
Another problem might be scaling font or glyph icon in combobox. In WPF this simplest and supported.

Perform some action when tabbing between labels?

I know that label can't receive focus, it doesn't seem to be responsive to tab switching. But all I need is perform some action when user uses tab consequently on a form which has only labels. For example, each label has an associated textbox but this textbox is hidden when the label is visible and vice-versa. What I want is allowing user to use tab to switch between the hidden textboxes on the form, normally, all the textboxes are hidden while all the labels are shown, the labels are supposed to be focusable so that when using tab, it can know that (as some event) to show the associated textbox and hide itself, when switching to another label, the current label whose the associated textbox is shown will become visible again and its associated textbox will become hidden.
I have to implement this kind of 2 in 1 control (textbox and label in a composited control) because I just want to show only the text (no border and background) as if the textbox has a transparent background and only show the textbox (and hide the label) when user need to edit (start by clicking on the field or using tab). This should have been easier for me if there was a transparent background textbox but there isn't a decent one in the world of windows forms. Please notice that I also know of the alpha blend transparent textbox presented in an article in codeproject but it can't meet my need because the text is rendered wrong with ugly border around the text path (some kind of missing antialiasing but it's even worse than that).
I'm really pity if this mechanism can't be implemented, the forms look better when all the fields seem to show info only but a click or tab switch can let user jump in edit mode.
I hope there is some solution out there. Thank you in advance.
I found this solution by a whim in my mind. I didn't think there was such a solution but it does help solve my problem (and I'm sure many others will benefit from it). Simply I have to create my own Label inheriting UserControl. I didn't thought of UserControl before and it is very helpful. Focusability, transparent background, borderlessness are all which can be done easily to a UserControl. The only custom feature I have to do myself is rendering the text which is also very simple and there are many ways to do. I just add a Label to the UserControl and set Label's Dock to DockStyle.Fill, adjust the height of the UserControl properly and that's all.
Thank God helping me think of UserControl before trying any other complicated solution such as listening to TAB and SHIFT + TAB keypress events.

Converting GUI from C# to Java

I'm trying to convert a form which I currently have in C# to Java, utilising layout managers. And it's turning out to be a nightmare.
I've tried setting the sizes of the components, however no difference is present. Also, I cannot get the labels and textboxes to move closer to each other.
For all of the buttons and text fields, just put then in a Panel that has nothing but that one item in it. That will prevent the button/textfield from filling the entire space in the layout.
Other than that the only thing it seems you need to do is put a bit of a margin around the whole thing so that your items aren't right up against the edges of the window.
Try GridBagLayout instead of GridLayout.
GridLayout forces all components to be the same size.
See also javax.swing.Box, to put the label - text field pairs in one pane.

How Can I Intelligently Implement Auto-Resizing in a Visual C# Winforms App?

My application (which I am using Visual C# 2008 WinForms for) involves a lot of generated controls. Specifically: grids of buttons, arrays of labels, lists, headings, etc... all populated so that they fit their containers appreciably.
I want users to be able to resize the main form, which obviously would require me to either destroy my generated content, and remake it at the proper size OR I could index through every control, figure out what it is by name and type, and re-size each item individually. I would have to do this while/after the form resizes.
Are there any more intelligent ways of doing this? Dock and Anchor don't quite apply here because I am dealing with items that don't make up 100% of a dimension (for example, grids of buttons).
Hard do give a reasonnable answer without seing just how complex the layout in question is.
But in principle, you should use a layout container such as FlowLayoutPanel or TableLayoutPanel to do the job they were designed to do. If one does not do the job, just nest them.
Docking/anchoring is probably the answer here. You need to anchor your grid to top/bottom/left/right or dock it (same effect, but the grid will fill the parent control).
If this is done right your control(s) will re-size with the rest of the form just as if you created everything in the designer.
I believe something like this would work:
Control.Anchor = AnchorStyles.TopLeft | AnchorStyles.BottomRight;

Categories