I am attempting to insert a panel into my WPF application that would have a few very specific behaviours:
1.) Wraps content evenly. Starting from the top left corner and running downward, before moving to the next column.
2.) Allows me to define a maximum number of columns to wrap to. For my purposes, this number would be between 1 and 3.
3.) Allows me to set an initial height, but it will also grow to accommodate additional items. (Only setting an initial height because my content won't wrap without it. If I leave it auto, it all comes out in a single column regardless of whether it fits on screen or not)
At this point, I have concluded that what I'm attempting do will require a custom panel, but I'd like to ensure before I begin that process (and learning how to do so) that I'm not missing a much simpler answer.
A WrapPanel can be set to wrap vertically, but you have no control over the number of columns.
A UniformGrid would offer you control over the number of columns, but wraps horizontally not vertically.
In short: you need a custom panel. The built-in ones do not offer the combination of features that you want.
UniformGrid has a LayoutTransform property, which can be used to transform it in order to change the position/rotation of the elements inside. But it will also transform the content.
Some more tricks involving Setters on the types of the items inside your UniformGrid and the content can be transformed again to retain the desired "original" orientation.
You can learn more in this tutorial.
Alternatively, it seems that the Extended WPF Toolkit contains its own implementation of UniformGrid, with an Orientation property, the only problem being that it won't grow to accomodate the number of items; instead, it will obey to an arbitrary Columns property.
Then again, you may be able to change the value of this property each time you add a new item/resize your UniformGrid, but it will be some more manual work and may potentially lead to code behind, which could be seen as an issue if you're working in MVVM.
Related
Just recently started WPF and well into the run before I can walk stage.
I have made a custom control that I need for one of my projects, and it looks almost exactly as I want. It currently looks like this:
whereas I need to add a scale to the horizontal and vertical sides, with a mark and a number of how many cells we are at, skipping a predefined number which should look roughly like this:
The model that provides the data for the control has the data, the size of each cell (and thus the overall size), all the label text, and a step value for the X and Y control.
The control is a grid with the title in the top row, the y title, space for the numbers, the control in the second row and the space for the X control in the next and the title of the x axis in the last.
If I was doing windows forms I would just draw in manually and it would be pretty simple, but I would like to learn this properly.
After a lot of googling, I can't find a way of doing this easily in XAML, so I assume I have to do a custom control on a canvas, or is there an obvious way that my inexperience with WPF is missing?
There is nothing out to the box but there is a control you can work off of to get what you need. Investigate modifying the TickBar.
An initial search turned up How to use string values in place of ticks on WPF Tickbar?.
I want a grid in my page to have a single column in portrait mode and have two columns in Landscape mode. Some of the content should move to the second column when the device is Landscape. I've tried to do this but couldn't.
I'm doing everything from code behind. Generating the grid, adding children etc. When Orientation changes, I destroy the current layout and create a new one. The problem with this approach is, any entered data will be gone. It's a huge code and not possible to put here. I want this layout change to happen automatically. So, any data that is entered is preserved after the orientation change.
Any help would be appreciated.
The trick is to have one grid that accommodates both states. You can use VisualStates to assign different Grid.Row, Grid.Column, Grid.RowSpan and Grid.ColumnSpan values to controls. This is done using Blend and is declarative in XAML. you give each state a name. In the code you detect size change of the window to trigger the different states using the VisualStateManager.
You can also do this without VisualStates. In that case in the event handler of the SizeChanged you have to set the appropriate values for all the controls yourself.
In Windows 10 UWP it got much simpler using RelativePanel. You can position controls in a more flexible way then with grids.
Martin
What I want to create is a list view that will resize itself in order to show all items. Normally I would use AutoSize, but this won't work here. Any other options how can I make ListView expand and shrink to fit all?
You will have to manually calculate your desired height and set it as items are added/removed.
Detecting item addition or removal isn't directly supported - so you'll either need to create your own Add/Remove Item calls for clients to call, or handle LVN_INSERTIEM type messages from WndProc.
Auto-sizing controls are usually trickier to use - as you have to track Min/Max sizes, allow room on the owner, and usually add to an awkward usability point for users. Only do something like this if typical solutions (i.e. scroll bars) truly can't work for your need.
"AutoSize" property is not supported for the "ListView" control. As #JohnArien mentioned, you will have to programmatically re-size your list view control's size according to the number of items available. But be warned that this may not be a good idea in terms of visual appeal of the Form. Your form design might look ugly if you change the size in run time. More over these types of controls are expected to expand their client area within the given size with the help of scroll bars. I would strongly suggest you to reconsider this option.
I need to build a WPF control that looks somehow similar to this:
alt text http://img251.imageshack.us/img251/6857/circle.png
Where each color should be clickable and resizable (or selectable).
This control will be used to set modes on the hours of a day.
I've thought about making 24 buttons that would be arranged in a circle:
alt text http://img684.imageshack.us/img684/2184/buttonsk.png
Another idea was to draw a complete circle and calculate user mouse click's position for the selection and draw several circles to represent the data.
Any other/better ideas on how to build this?
(please excuse my poor drawing).
I think you would get odd edge-effects with multiple overlapping or touching controls. So I would make a single custom control to do this. It would convert the mouse position on button down to a slice, and then do the appropriate action.
With a single control, you could also come up with a rational way of dealing with keyboard input and for showing selection and allowing for multi-select behavior.
It sounds like you want a customized ListBox (multiple items that are selectable/clickable). For the layout you would want to use some type of RadialPanel as the ItemsPanel. You probably also need to change the ItemContainerStyle to make your ListBoxItems look like what you have above, probably with some triggers to change colors based on selection state. Depending on what behavior you need from your items you may need to create custom ListBox/ListBoxItem derived custom controls but in a lot of cases the built-in behavior will get you a long way. To reuse it as a single unit you could wrap up the ListBox with its 24 hour items and customized templates in a UserControl and expose the selection data in whatever form you need as a Dependency Property (like an IEnumerable of the data items representing the selected hours).
Does that help you get started?
I'm trying to use the windows native (Theme-aware) header control to display just some column headers. The main purpose is to avoid manually drawing the column headers and rely on the natively supported functionality.
So the 2 options I was thinking of are:
Use a HeaderControl, and add columns to it (I can't seem to find a header control supported by WinForms).
Use a ListView control, and tell it display no rows (or basically set its height to the height of the column header) - can't find any way to determine which height should I assign to the control.
Any good ideas much appreciated!
There is no HeaderControl for WinForms in the .NET framework so far (the ListView utilises the ColumnHeader class but this is only useful with the ListView). If you are only targetting Microsoft Windows, you could look at wrapping the Win32 control for use in .NET although I expect that will be substantial work.
Your second option is a valid possibility even though it feels somewhat clunky. I can see difficulties arising in getting the list to size properly such that the header and only the header is visible.
A third option would be to roll your own HeaderButton that represents one column (like ColumnHeader) and use the theme drawing calls to draw it, then just combine them in a FlowLayoutPanel or TableLayoutPanel into your header bar. If you want resizing, you could make the HeaderButton have a grab region that you can pick up and alter its width.
I think the third option will be reasonably simple to create, even with the sizing ability, so I would recommend taking that route (I might even give it a go myself when I get home tonight).