I have been trying to create a WPF control similar to how JIRA's menu works, and Googling around for the past few days hasn't really shown me anything helpful for overriding the menu template (or if that is even what I should be doing).
As a reference here is the type of menu I am trying to implement:
As one can see from the images, I don't want the standard menu that displays a popup next to the current menu item list, but it should instead take over the container host and display the current parent menu item at the top and then its child items under it.
As I said, not sure menu is even the correct control to attempt to override, but I'm not really sure what else to try to Google either. It seems tantalizing similar to menu (overriding the menu items is easy to get them to display the look and feel I want), the trouble is how to get the menu item's parent to show at the top and reuse the entire menu area... it's almost as if the menu item would somehow have to interact with the menu, but that would kind of defeat the purpose of the plug-in methodology of WPF.
If possible, it would also be nice to not have a write a completely new control, but style something else existing, if that is even possible. If writing a new control is necessary, then I would do it, but this is more an excercise in wanting to know if it is even possible to style a menu (or something else) in this way so it can be easily reused across the application.
Related
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?
Has anyone seen an implementation or plugin for extjs where you can "pull off" or "dock" tabs/windows the way you can with a browser? Is it even possible?
Searching has not revealed much but I did come across a proposed solution in an older version:
http://www.sencha.com/forum/showthread.php?16842-Dockable-floatable-panels-in-ExtJS
#DmitryB
To clarify, in chrome if I have multiple tabs in the same window like so:
And I "drag" one of the tabs, it pops off into a new window:
I imagine you might accomplish this by moving the content of the tab panel into a window but not sure how to go about it.
In a nutshell:
- Make the tabs draggable, watch for the drag event and mark the
tab-strip as your "safe" zone
- When a tab is dragged and then "dropped" (as in, the drag event ends) you do a check:
> Is the tab within the safe area?
No: Create a new Ext.Window at the x/y of the mouse, copy the components/HTML
out of the original panel and insert them into the new window. Destroy the
original panel.
Yes: Do nothing.
Unfortunately, I am still quite jaded from learning D&D in ExtJS3, so I can't offer any help with this and real code pertaining to ExtJS 4, however the concept seems relatively straightforward to me. I would say you're going to probably want to do your best to NOT have this be flashy - unless you REALLY REALLY need to, I wouldn't worry about showing the panel's contents while you drag the tab - much less show the panel itself. Just let the tab element get dragged around the screen and copy when it's released outside of the safe zone.
I'm looking to add a 'close' button to my main window's menu. An example can be found in the picture here: http://ifyoucodeittheywill.com/img/crimson-editor.png
(So, there's the normal close button in the window caption area, but, there's also a close button in the window's menu bar -- on the far right).
I'm using basic win32 API's, though an example using MFC would also be fine.
Does anyone know how to do this?
Thanks,
Andrew
These buttons usually come with MDI windows. However I'm pretty sure the depicted application uses either its own, or more probably some advanced third party toolkit. Because, to be honest, what the Windows API and MFC (which is just a classed wrapper around the windows API) give you for GUI programming is unbareably limited.
If you want to design neat UIs steer clear from MFC and better have a look at something like Qt, wxWidgets or the like.
A really simple way of doing this is to use a regular menu item, using AppendMenu, but use the following flags:
MF_BITMAP with a close button bitmap, or MF_OWNERDRAW or to draw it yourself
MF_HELP (aka WM_RIGHTJUSTIFY), a not-very-well documented flag, which will justify the item to the right.
Here's one reference to MF_HELP that I found on msdn - it's actually about using the Win32 API to right-justify a menu item, but using Visual Basic.
MF_HELP (defined in winuser.h) is something of a holdover from Win16 days, back then, the convention was to right-justify the Help menu item, so it would stand apart. It was 'renamed' - an additional #define added with the same value - to WM_RIGHTJUSTIFY around Win95.
Note that bitmap menu items aren't accessible (eg. to users that are relying on a screenreader to read out where they are on the screen); if taking this approach, then at least add a regular 'Close' menu item elsewhere in the menus (eg. under File), so that a user doesn't have to rely on this item, and can also close it through usual means. Also be sure to implement the Ctrl-F4 shortcut, which is what most applications that support multiple documents or tabs use to close the current item.
By all means do not try to create this behaviour yourself. This is functionality that you get "for free" if you are using the MDI architecture of MFC. The close button "next to the menu" as you call it closes the active MDI child window. If you are not using the MDI architecture then there is no point in trying to add a close button there. Can you explain if you are using the MDI architecture?
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.
What do you think is the best way to present a hierarchical list of functionality to users within your traditional WinForms application? (A menu system - Assume functionality can be split into a small number of modules and sub-modules but with no fixed depth in terms of those sub-modules).
Do you like the traditional drop down menu system, ribbons, docked toolbars, a treeview approach or any other innovative ideas?
An important thing to consider in your design is Usability vs Discoverability.
The best solution depends strongly on who you users are. The UI requirements for a kiosk application for tourists in a city centre are very different to those for a control screen at a power station...
I often have a toolstrip docked on top for those functions that is most used. And all other as drop down menues with hotkeys set.
If I have a list that can contain different types of items I use a bottom docked toolstrip that change its content depending on the selected item in the list. That way I only have buttons/icons that is relevant for the task and not a bunch of disabled buttons irritating the view.
I also add a context menu for the items that automagically fills with the same choises as the bottom toolstrip. That way I give a faster way to get to the "action" without having to move the mouse down to the bottom of the screen.
I really hate the ribbon-thing (as a user) so I dont use it as a programmer in my projects.
In my opinion the best way is to make sure everything can be done in several ways.
Menus
Keyboard shortcuts
Toolboxes ...
So the user can choose it's way around.
What I really like to see in more application is that a menu or option is directly attached to the selected item (control) a user is looking at. And of course the menu is in context with the given content.
I have implemented this in my open source project Monex and I really like using it myself. Just look at this screenshot.
You could always opt for the increasingly ribbon control. Microsoft/Office interfaces have a habit of becoming the user's expectation of norm (eventually).
Menubars, toolbars, and Ribbons are used for commands, where the user selection of an item acts on a data object displayed in the window or the application as a whole. Which one you use depends primarily on the number of commands in your app.
Toolbar alone: About 20 or fewer commands. Provide both icons and text labels for each command button. Represent the hierarchy by separators. Have no more than two levels –flatten your hierarchy accordingly.
Menubar with toolbar: Over about 20 but less than about 1000 commands. Up to twenty menu items on a single menu (using separators) is generally better than cascade menus –flatten your hierarchy accordingly. Common commands should have accelerators. Generally limit your toolbar to no more than 30 of the most commonly used commands, primarily commands otherwise only accessible from within a dialog box. Consider not having toolbar controls for menu items that have accelerators –one good means of expert access is often sufficient.
Ribbon: Over 1000 commands. A Ribbon is little more than putting different menubars-and-toolbars on separate tabs. To work well, the tasks associated with each tab (the top of your function hierarchy) should be non-integrated –users relatively rarely switch from one to the other. The Ribbon is also tends to be more effective for promoting discovery of advanced features at the price of discoverability and efficiency of basic features.
Check if items in your function hierarchy may be better represented as attributes rather than commands. Commands carry out a process, such as Open, Find, and Copy, while attributes change specific characteristics of something, such as Font, Size, and angle of view. Attributes are set by field controls within your window (e.g., text boxes, check boxes, and dropdown lists) rather than menu items, toolbar controls, or Ribbon controls.
A window-full of such field controls (or other representations of data objects) is a content block. Tree controls may be used to control what content block is shown. Like tab controls, they are preferred over multiple windows when the user frequently switches among the content blocks and does not compare content blocks. Trees are preferred over tab controls when the amount of content will not fit in a single row of tabs.
Do not have any empty nodes in your tree. Anything the user clicks on should display a full pane of content –flatten your hierarchy accordingly, even going to the extreme of using a list box rather than a tree.
If users tend to select one content block, complete a task there, then leave your app, then consider a “home” page displaying a full-page menu of all the content blocks, possibly spatially arrange according to your hierarchy, each accessible with a single click.
In my opinion there is no definite answer to your question. It always depends on the menu you are presenting to the user and the users that are expected to use the application
A menu with standard/common functionalities is probably best presented Office style meaning drop down menus or the new Ribbon style.
A menu with custom functionality and, as you state multiple modules and submodules with different depths, is often best presented as a TreeView-like menu.
Looking from the point of the user, a typical user will do just fine with a standard menu whereas a more advanced user won't mind more advanced features like keyboard navigation or possibility to hide/show the menu or dock it to the other side of the window.