FixedPage and Grid.IsSharedSizeScope - wpf

I am trying to save an WPF UI to an XPS file stream.
Everything works as it should but there is one problem with Grid that use Grid.IsSharedSizeScope. Although when WPF UI rendered the column sizing is honored it is ignored when the UI saved to XPS so there is no equal column sizing.
Does anybody know why this could be happening and if there is a workaround ?

I wrote an application that generates various printed reports, which involves programmatically creating XAML controls and adding them to a FlowDocument. I remember hitting an issue where "Auto" widths are ignored, so had to use numeric or "star" values. Rendering the exact same XAML "to screen" worked fine.
Perhaps your shared size scope problem is related to the same problem. I remember reading about this "known issue" way back when I wrote this stuff, but don't have a link sorry.
I've just looked at my reporting code and didn't find anywhere that I've used shared size scopes (which is odd given their tabular nature), so perhaps I hit the same issue at the time.

Related

Protecting custom inline elements in WPF RichTextBox

I'm currently spiking with the WPF RichTextBox before I decide whether or not it can be used in a project of mine.
What I need is to have elements of text representing various objects (other texts or objects), a bit like a WIKI but not quite. Clicking on such a text will make stuff happen, like navigating to other texts or providing additional options.
Anyway, as these little text bits represent other objects I would like to protect them but I have succeeded with this only in part: The user cannot position a caret inside such a text element and edit/delete it but it is still possible to make a selection and delete/replace it, including my custom elements.
Have anyone travelled down this road with the RichTextBox? My latest experiment was to simply record all custom text elements when being part of a selection and then restoring them after the (destructive) edit. That fell apart because I can't find a way to re-insert my custom inline elements (derived from the Run class). The only way I've found to programmatically insert a Run (based) element at a specified position (TextPosition) is via its constructor.
Well, any hints would be greatly appreciated.
You are really looking for a FlowDocument, not a RichTextBox.

MFC: how to render an Aero-style combo box for owner draw?

I have inherited a large MFC application which contains a CComboBox subclass that overrides OnPaint. Currently it does all its drawing by hand (with lines and rectangles), and renders a combo box that looks decidedly Windows 98-style. However, it otherwise works great and provides a lot of useful custom functionality that we rely on, and rewriting the entire control is probably not an option.
I would like to modernize it so that the OnPaint draws in Aero style where available (falling back to the old code when modern theming is unavailable). I've done this with some other custom controls we have, like buttons, and it works great for our purposes. I know there are some tiny behaviors that it won't get right, like gentle highlights on mouse-hover, but that's not a big deal for this app.
I have access to the CVisualStylesXP ckass, so I've already got the infrastructure to make calls like OpenThemeData, GetThemeColor or DrawThemeBackground pretty easily (via LoadLibrary so we don't force Vista as a min-system). Unfortunately, I don't know the proper sequence of calls to get a nice looking combo box with the theme-appropriate border and drop-down button.
Anyone know what to do here?
Honestly, I don't know why they originally tried to override OnPaint. Is there a good reason? I'm thinking that at least 99% of the time you are just going to want to override the drawing of the items in the ComboBox. For that, you can override DrawItem, MeasureItem, and CompareItem in a derived combo box to get the functionality you want. In that case, the OS will draw the non-user content specific to each OS correctly.
I think you best shot without diving in the depth of xp theming and various system metrics is take a look at this project: http://www.codeproject.com/Articles/2584/AdvComboBox-Version-2-1
Check the OnPaint of the CAdvComboBox class - there is a full implementation of the control repainting including xp theme related issues.
Not sure if it's the same situation - but when I faced this problem (in my case with subclassed CButtons), solving it only required changing the control declaration to a pointer and creating the control dynamically.
Let's assume that your subclassed control is called CComboBoxExt.
Where you had
CComboBoxExt m_cComboBoxExt;
You'll now have
CComboBoxExt* m_pcComboBoxExt;
And on the OnInitDialog of the window where the control is placed, you create it using
m_pcComboBoxExt = new CComboBoxExt();
m_pcComboBoxExt->Create(...)
Since this is now a pointer, don't forget to call DestroyWindow() and delete the pointer on termination.
This solved my particular problem - if your control is declared in the same way, consider giving it a try.

How to deal with big project in WPF

I am new to WPF environment and I am experiencing some problems like if there are alots of things how do we manage them.for example I have three borders each of same size same location and they contains controls like textboxes etc etc we construct them sequentially but when it comes to edit we get in trouble modifying the border that is at bottom.
So in short how do we manage many controls on single page so that it remains easy to edit
Not sure I completely understand your concerns, but here are several point that make editing WPF UI pretty easy:
Correct usage of layout panels. If you will use approach with absolute positions for each control then it might become a nightmare to move or resize some of your controls. Correct layout (and panels such as DockPanel/StackPanel/etc) might help you a lot.
Incapsulating repeatable parts. WPF has a lot of feature to avoid repeating UI code. I'm talking mostly about Styles and Control templates at the moment. If you have your borders repeating through the entire window, maybe you should think on extracting this border as a ControlTemplate for ContentControl for example?
but I've found that encapsulating controls such as borders, textboxes etc in User Controls helps to keep things well managed (not to mention helps reduce code), similarly using a Resource Dictionary to store styles/animations is useful for very big projects (remember though that the local resources will take precedence when applied so remove them if they not in use)
furthermore, using Layout Panels such as Stacks,Grids and Dockpanels allows you to collapse User Controls when not needed or otherwise (also I've found that for some reason, Grids allow controls to overlap (when items are not correctly ordered in Grid Rows and Columns) which can lead to some elements not being seen in design.
Plan your layout properly and think through which Panels would be best for them, having to go back much later and change can be annoying (though admittedly it happens).
Also remember to use partial classes to properly structure your stuff, having to read through 1000+ lines of code to find something can be a nightmare.

WPF: Best method for printing paginated datagrids

Boy did I get an education looking into this. I guess I've been spoiled by Powerbuilder, which has fantastic functionality for this out of the box.
Does anyone seriously write custom documentpaginator objects to handle reporting needs for their LOB apps? I want to be able to print "for free" and not have to code like crazy just to take whats on the screen and throw it on paper.
How are people doing this? Does anyone have a recommended 3rd party for allowing printing of largish datagrids?
Thanks
Paginating datagrids is a huge, huge pain. Simply drawing the grid on a page will not work as you have to handle things like fixed layout, expanding cells horizontally and vertically to show all data, word wrapping, splitting columns and rows into the page margin, splitting cells that overflow a page into multiple pages. Remember you can't scroll or resize a control on a piece of paper. Even if you find a magic control that can do all that, a grid with borders, shadows, and backgrounds that look good on a screen won't look good on paper.
For an old WinForms app that printed datagrids we implemented a completely separate report API for printouts. We printed the underlying ADO.Net dataSource using the free ReportViewer control. A tutorial is at gotreportviewer.com.
I've found the easiest way is to implement a generalized DocumentPaginator class for paginating anything I can put on screen. With my DocumentPaginator I don't need to worry about printing because I can take any arbitrary WPF control and tell it to print, and it will take multiple pages if necessary to display all the data.
I also use an inherited attached bool property "PrintView" that the user can control. Some of my controls change their appearance somewhat using a trigger on the "PrintView" property, so they will look better when printed.
I describe my DocumentPaginator solution in more detail in this answer, including a description of the algorithm required.

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