Inherited forms are jumbled in designer - winforms

I have an inherited form that adds some objects to the base form. Hoewever, after I am done designing and close and re-open the designer on that form, a lot of objects are placed incorrectly, both location and size. This means I have to reposition a lot of objects each time I edit this form, which is quite annoying.
Before:
and after a simple save -> close -> open:
Edit: the problems seem to only be with items that are anchored on the right side or the bottom.

Related

Winforms appearance at 100%,125%,150% Windows scaling modes, and alleviating need to constantly edit Designer.cs class every time I update the GUI

I'm developing in Winforms with a .NET 4 profile in Visual Studio 2010 at Windows' 100% scaling (96dpi) on Windows 10.
As per the advice from this highly rated answer, I set dpiAware to true in the app.manifest file, set the AutoScaleMode of the main Form to Font, and since I have splitContainers in the Form, but they very unfortunately don't have an AutoScaleMode property in the Wysiwyg Designer, I also have to add these lines to the Designer.cs file:
*.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
*.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
This ensures that if the user happens to use Windows in 125%, 150% or even other scaling modes, then the GUI will resize properly, without some components being too small or too big.
Unfortunately, as per the advice of the aforementioned link: "Only the controls in the Controls lists when ResumeLayout at the end of InitializeComponent is called will be auto-scaled", which means I need to put the above two lines in the Designer.cs file. I can't simply put them later in the Form Load event.
Unfortunately, this means that whenever I update or move about a widget/button/label in the Wysiwyg editor, the Designer.cs file is automatically recreated, and I lose my two lines of code above. So I have to keep remembering to put them back in every time I update the GUI in the Wysiwyg editor.
The link also supplies a potential solution to avoid this ugliness by partially avoiding the use of the Wysiwyg editor, and instead creating the splitContainers programmatically in the Load event. I quote: "if you dynamically add controls, then you need to SuspendLayout(); AutoScaleDimensions = new SizeF(6F, 13F); AutoScaleMode = AutoScaleMode.Font; ResumeLayout(); on that control before you add it in".
The problem there is that I have a ton of splitContainer code to move over (such as objects being added to the splitContainers), and it will ruin the look of the Wysiwyg editor (I want to see my splitContainers thank-you-very-much as they are a crucial part of the GUI and have many elements/widgets inside that I also want to see when designing!).
My question is if I can get the best of both worlds: Keep the look of the splitContainers and contents in the Wysiwyg editor, while keeping the functionality of proper scaling by utilizing the two lines of code above (*.AutoScaleMode = ... and *.AutoScaleDimensions = ...) which seemingly must be in the Designer.cs file before *.ResumeLayout() is called.

putting artboard XAML on separate window / screen

Simple question, but is there any way of putting the artboard designer on one screen, and the XAML on another in Blend 4?
It's a real pain constantly flicking between the two when I've got three monitors to play with!
Short answer, no.
What you can do however though that I do often is set your Designer & Code View to be side-by-side via View -> Split View Orientation -> Split Views Horizontally then drag the Blend window across two of the screens with the split obviously between the two screens. That works pretty well.
Otherwise you could have the design open in Blend in one screen, and the xaml open in VS on another screen...becomes a pain though since whenever you save on one, you'll be prompted to update on the other.
Wish there was a better way, but I'm pretty sure none exist besides those mentioned. Hope this helps.

WPF Printing multiple pages from a single View Model

I am currently a little bit troubled by the following problem. I have a user interface which basically shows a graphic (a canvas made of Lines, Circles, ... these are all WPF objects). Depending on the selection a user makes in the menu, some items get deleted and some get added. So the basic image looks the same, but a few modifications are made.
The user has the possibility to select - say - 10 different "pages" by clicking a Next/Previous Button.
I am using MVVM Light and my ViewModel contains all the items of the graphic (all Lines, ...).
Now I would like to print that graphic to multiple pages. The first page should contain the graphic with changes from page 1, the second page contains the graphic with changes from page 2 and so on. The actual number of pages is dynamic. I track this with a property CurrentPage and a property PagesTotal.
Whenever I push the "Next" button, this causes a command to be executed which will change the variable CurrentPage and also makes sure that the correct items are displayed.
Now I would like to print this but this is where I'm stuck. I dont' mind leaving the MVVM zone and doing some dirty work in code-behind but I would refuse to draw everything again like in the old GDI days.
Any ideas are really welcome.
Create a UserControl containing your display logic (you graphic, for instance). Grab you ViewModel list and project then in UserControls, setting each ViewModel as each UserControl's DataContext.
Force each one to render calling Measure with infinite value and then Arrange with the resulting DesiredHeight and Width. Then follow the procedures to print WPF visuals (link link link).
Essentially, this should be quite simple if and only if your views work independently; i.e. your ViewModel doesn't contain UiElements that are placed into your View.
Simple solution is to basically print your visual root. If need be encapsulate your Views in a user control first.
PrintDialog printDlg = new PrintDialog();
UserControl1 uc = new UserControl1();
printDlg.PrintVisual(uc, "User Control Printing.");
Reference
Alright, I have to admin that I now switched back to doing the printing through code only. I would have really liked doing it "WPF-style" but handling the multiple pages issue was just too much trouble.
Anyway, there is still one issue regarding the printout left but this will be another question.

Creating lots of user controls in WPF?

Is it normal in a WPF app to create a lot of user controls in order to separate concerns that would otherwise be crammed in a single window with a huge XAML hierarchy? I'm finding that I keep making new user controls, even though I don't intend to reuse them, just so that each of my sub-components has a separate task. I'm also giving each of them their own view model, instead of binding things to properties on one master view model.
Is this normal? I feel like from a code cleanliness perspective I'm doing the right thing. But from a WPF perspective, I feel that this can't be right.
For example, let's say you have a list on the left side of the window, and when you select an item, it changes what's displayed on the right side. There are also buttons above your list to manipulate it, adding and deleting items for example. I would be inclined to pull that whole list out as a UserControl, which would contain just the list and the control buttons above it. Then the main window would just include my new control.
Am I going overboard?

Complex .Net 2.0 Windows Forms control: where to start?

In order to make a convenient UI for an .Net 2.0 Winforms application I am working on, I have need for a control that I'm pretty sure goes beyond the "out of the box" behavior of any standard control. A mock-up of what I'm trying to achieve follows:
Mock up http://www.claware.com/images/temp/mockup.png
Essentially, this part of the application attempts to parse words into syllables from tribal languages (no dictionary to refer to; any and all unicode characters are possible.) By the time the user gets this far, he has already defined the vowels / consonants in his language and some other configuration. There is then an iterative process of (1) the application guesses which syllables exist in the language based on some rules, (2) the user refines the guesses, selecting the correct parsings or manually parsing a word, (3) the application "learns" from the user's feedback and makes smarter guesses, (4) repeat until the data is "good enough" to move on.
The control needs to present each word (the grey headers), then all the syllable break guesses (the white areas with dots separating the parts of words.) There is also a way to manually enter a parsing, which will display a text area and save button (at the bottom of the mockup.) When the user hovers over a guess, the background changes and "accept / reject" buttons appear. Clicking on the accept, or entering a manual parsing, removes the entire word from the list. Clicking the reject button removes just that item.
I'm by no means 100% sold on the formatting I have above, but I think you can get a general idea of the types of formatting and functional control I need. The control will also scroll vertically--there may be thousands of words initially.
My question for you experienced WinForms developers is: where to start? I would really, really like to stay within the .Net core framework and extend an existing control as opposed to a third-party control. (At the risk of starting a religious war: yes, I suffer from NIH-syndrome, but it's a conscious decision based on a lot of quick-fix solutions but long-term problems with 3rd party controls.) Where can I get the most "bang for my bucK" and the least reinventing the wheel? ListView? ListBox? ScrollableControl? Do I need to go all the way back to Control and paint everything manually? I appreciate any help that could be provided!
[Edit] Thanks everyone for the ideas. It seems like the most elegant solution for my purposes is to create a custom control consisting of a FlowLayoutPanel and a VScrollBar. The FlowLayoutPanel can contain instances of the custom controls used for each word. But the FlowLayoutPanel is virtual, i.e. it only contains those instances which are visible (and some "just out of scroll"). The VScrollBar events determine what needs to be loaded. A bit of code to write, but isn't too bad and seems to work well.
I would look at the TableLayoutPanel and FlowLayoutPanel controls. These will let you organize a series of controls with moderate ease in a vertical fashion. I would then create a UserControl that consists of a label and 2 buttons. The UserControl will expose properties like Text and events that are exposed for the button clicks.. For each entry in the list, you will create an instance of the UserControl, assign the text value, and handle the click events. The instance will be placed in the Table/Flow panel in the correct order. Both of those layout panels do allow for inserting items between other items so you can add/remove items from the list dynamically.
Edit:
Given the length of what you are trying to render, I would consider using the DataGridView and do some custom rendering to make it perform how you want it to work. Using the rendering events of the DGV you can merge columns, change background colors (like highlighting the dark gray lines), turn on/off the buttons, and handle changing the grid into edit mode for your rows to allow modification or inserting of new values. This method would easily handle large datasets and you could bind directly to them very easily.
Well, this certainly looks like a candidate for a custom component that you should be creating yourself. You can create this using standard .Net drawing commands along with a text-box, and a regular button control.
Now you want to find out where to start.
Create a Windows Forms Control Library project.
Drop in the textbox and the button control.
The panel drawing code should preferably be done by code. This can be done using the regular GDI+ commands.
Edit:
Here's another idea, and one that I've practically used in my own project with great success.
You could use a web-browser control in the app, and show your data as html. You could update the source of the web-browser control based on the input in the textbox, and clicking on the links in the web browser control will give you the event that you can trap to do some action. Your CSS will work.
I used this technique to build the 'desktop' in an app I made called 'Correct Accounting Software'. People loved the desktop so much that it is one of the best loved features of the app.
Here's how I would do it:
Create a custom control. In this custom control, have a ListBox atop a LinkButton, and when the LinkButton is clicked you can make it give way to a TextBox. The ListBoxes will have the top row unselectable... you can probably get the rest from there. When you get your list of words, fill a Scrollable of some kind with one control for each word:
(foreach String word in words){
myScrollable.add(new MyComponent(word));
}
From there, I'm not sure what you want to do with the boxes or the data, but that's my initial idea on the UI setup.
Use the WebBrowser control and generate the HTML markup into it using DocumentStream or DocumentText.

Resources