THis is a followup to my previous question "Font-dependent control positioning." It's an attempt to solve the real problem behind that question, perhaps in ways different than the one I was asking about.
Example of the problem statement: I want a checkbox that says "Adjust prices by <X> <Y> after loading," where <X> is a number---adjustable with a NumericUpDown---and <Y> is either "percent" or "dollars," with the choices being made by a ComboBox. This will be on a single line.
The complication: I want to be able to change my fonts for all these controls (basically setting them to System.Drawing.Fonts.MessageBoxFont, which is Tahoma 8 pt on Windows XP/etc. and Segoe UI 9 pt on Vista), without messing up my layout, which with my current Position-property--setting paradigm does not work.
More generally, I'd like the controls to be dynamically laid out in a font-independent way, so that the <X> NumericUpDown fits snugly into the space between "by " and the <Y> ComboBox, and similarly the <X> ComboBox fits in with respect to the <X> CheckBox and the string " after loading" to its right.
The part everyone seems to miss: This is all nested within a CheckBox. So, ideally, clicking on the words "after loading" should check/uncheck the checkbox, and draw that little highlight rectangle around "Adjust prices by after loading." So just slapping an extra Label on the end doesn't work, because then it doesn't toggle the CheckBox; similarly, trying to band-aid things by hooking up such a Label's Click event won't produce the desired highlight-rectangle.
Solutions? At this point I'm thinking either:
Rethink the problem, somehow, maybe with an ugly solution like two separate lines of text: "Adjust found prices after loading" (CheckBox), "Adjustment amount:" (NumericUpDown and ComboBox). This is really bad because my options box is absolutely full of options of this type (i.e. the type in the example), so it would at least double in vertical size.
Some sort of custom control? SplittableCheckBox?
Some kind of magic with a TableLayout control? (Pretty sure this fails at "the part everyone seems to miss.)
Give up and either go back to MS Sans Serif, or use Tahoma uniformly, or package Segoe UI with my application, thus disrespecting the system default fonts.
(New, via edit) Switch to WPF, if someone can convince me that it supports this scenario exactly.
If you have several options that follow this layout, why not create a user control? The user control will contain the CheckBox, a NumericUpDown, a ComboBox and a label for the "after loading". You can override OnFontChanged to adjust the location of the controls based on the rendering of the text with the given font. Add an EventHandler to the Label to check/uncheck the CheckBox.
As for having the focus rectangle surround all of the controls, you should be able to give the user control focus when one of its inner controls is clicked.
Related
Hoping you can help me as I have searched a lot of forums and did not find the same question, never mind the answer I need :)
I have a power point pack which I have put together. It is built to be a template for my team to use repeatedly and is set up using slide masters to control the layout. Each layout slide in the slide master includes two checkboxes to identify either a pass or a fail. My problem is that when you insert a new slide (by either duplicating an existing slide or adding a slide from the slide master layout), and change the checkbox value it also changes on the other slide. Is there a way either using some quick VBA or otherwise to stop this from happening and break the link between the two slides.
Any help would be really appreciated.
In a weird way, this is reasonable behavior from PowerPoint, though it certainly does seem bizarre.
Shapes on a master layout appear on any slide based on that layout. Though they appear on the slide, they're not editable on the slide; it's as though the slide were a clear layer above the layout, one that you can add more stuff to but that you can't "penetrate" to get at the stuff on the layout below.
Placeholders are a special case and so, apparently, are ActiveX controls like your checkboxes, which DO allow editing. So what's happening is that when you change a text box, you're changing the text box on the layout, not on the slide itself (the checkbox doesn't even exist on the slide ... you can't select and move it in normal view, for example, unless you go to the layout in Master view).
When you change the checkbox, you're changing the one on the layout, and since the checkboxes appear on any slide based on the layout, when you change the checkbox, you're changing the one on the layout, ALL of the slides based on that layout get the changed checkboxes.
Some mildly tricky VBA could look at each slide and if it's based on the layout that contains the checkboxes, COPY them to the current slide from the layout and finally make the checkboxes on the layout invisible.
The simpler solution might be to supply a sample slide with the checkboxes ON the slide and let the users copy/paste it into their presentations.
[later]
I've reported this to MS as not so much a bug as a design oversight; the behavior may make sense, but it's not useful and can mislead users (as you well know).
I'd suggest that you visit https://powerpoint.uservoice.com and suggest that ActiveX objects on masters/layouts behave more like placeholders ... spawn new instances of themselves when a new slide based on the layout is added rather than letting the user THINK that's what's happened.
I have a following requirement for a very complex UI. (Complex here means there are lot of controls in the form [approximately 100]). I am using MVVM (if my problem requires it to slightly go away from MVVM I am ok with it)
My question is for Editable ComboBox and TextBox. But I would say I like to hear a common algorithm which will fit all controls.
Requirement 1 : The user edits the content and goes to next control, the color of the control/text should become red.
Requirement 2 : When the user comes back to the previously edited control and enters the value which was initially present, the color of the control/text should become back to black.
I know the requirement is tough and I have been breaking my head to design a generic algorithm using which I can store the previous value and call a function to change the color of control.
To just give you all an idea, --> I tried storing 2 properties for every TextBox like Default_Text and Text. But since the number of properties are huge, the memory footprint is very huge. Also maintaining so many properties is very tough.
--> I tried adding a Dictionary to every ViewModel to store what values have got changed. But here the problem I faced was giving unique keys to all the controls in my application, which is not very helpful
--> I had even thought and tried about subclassing controls like TextBox, ComboBox and overriding some methods to suit my requirement, but sadly I failed miserabley when I started adding validations and all.
So here I am stuck with designing a generic WPF property system/algorithm to handle all undo redo functionality, changing styles of controls,etc!!!
It will be really great if you experts can guide me in right direction and also help me in developing such an algorithm/system. A sample illustration will be nice though!!!
I found an answer to the above problem. I used attached behavior for this. More details on this link Function call from XAML from StackOverFlow.
When I databind, I store the initial value of the DataBound variable in the Tag property by using Binding=OneWay. Then I have written a attached behaviour for LostFocus event. Whenever the user enters a control and then goes to other control, it fires LostFocus event and calls my attached behaviour. In this, I check whether the value is equal to the value in Tag. If it is same, I display in black else I display in red.
Attached Behaviour rocks in WPF. I can achieve anything from that cleanly without code cluttering!!!!
Another alternative is to use some "dirty" tracking in your models (or viewmodels) and bind to a properties isdirty (and convert it to a color).
Please refer this control
http://www.charlespetzold.com/blog/2009/10/Using-Text-Outlines-in-Silverlight.html
The formattedtext control is a shape which helps to generate the shape of the text with proper geometry. I would like to make this control act like a text box with cursors and features like typing in from keyboard.
Right now I use an invisible text box with a formattedtext control to act like that. But the cursor position always creates a problem when the size of the text is not equal to the size of the rendered text as shape.
Can anyone please show the way to achieve this.
Well, I built a syntax highlighting textbox using the method you describes.
Actually, at first I wanted to rebuilt everything too, but I thought : I have to build the caret fonctionnalities, the selection brush, manage a lot of different events, like selection with mouse or keyboard, deletion, Copy/Cut/Paste, etc etc...
That's a LOT of work, and windows users are used to select text in textboxes for instance, so this complex implementation cannot be left unimplemented. We must follow some Microsoft guidance on how a textbox must feel.
Actually, I think that building a new textbox from scratch is not the way to go. I suggest you to continue on your current method. If you have different fonts in the same textbox, use a RichTextBox, and handle the font changes in the textbox as well as in the formatted text.
Also, a good think to implement is to only draw the visible text with the formattedtext (but only if the user can write several hundreds of text lines).
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.
I have a list that the user can filter in several ways. two of which lend themselves to combo boxes and two that need to accept user input. For example, one textbox allows the user to type in any part of a list item's description, and the dialog will only present items whose description contains the text entered.
It is a dialog 'picker' type of window, so space is at a premium. I'd like for the text boxes not to require a traditional label. Instead, when the dialog is first invoked, the label (ie, "Description") is grayed out, centered, and in italics. Maybe a tool tip to further make it obvious to the user what it's for. When the user starts to type, the faux label disappears and the entered text is normal left aligned text.
Does wpf / silverlight have any native support for doing something like this? I guess it could be a combination of styles and eventing. I'd rather not invent any wheels that might be out there (I got the idea specifically from looking at Tortoise' "Show Log" window, but I've seen it before).
Does anyone have any sample code they can share to do this? Or a an alternative idea that also saves space and simplifies the layout?
Cheers,
Berryl
Kevin Moore's InfoTextBox, which is part of his Bag-O-Tricks is the kind of thing I was looking for, almost exactly. This is also the 'watermark' (great name - I would have found this sooner if I had known that) text box from another post.