Combobox for single data, but multiple representations - c#

I am not sure combobox would be the best vehicle for tackling this problem, but visually it is appealing.
Consider such data as angle -- I could enter its value in radians (single editbox) or in form of degree, minute, second, millisecond (4 editboxes) -- there are other representations, but those two will suffice here. For now I have combobox with mode entries "radians", "DMS" changing mode shows/hides appropriate control.
This approach has two flaws -- it takes a bit more space (for extra combobox with modes), and since each control is different is size everything on right of it moves.
So I am thinking about more direct approach, instead selecting mode, which in turns switches visibility of given control, would it be possible to put each control inside combobox, and combobox would then select that control. The target data would be exactly the same for each row (angle), but each row would have different control, because each row would mean different representation.
Is doable with combobox or am I banging at the wrong door? If combobox is suitable for this task, how to do it?

I was so focused on data binding at the combobox level that I didn't notice that the solution uses the basics of combobox.
So first, for the moment forget about combobox binding to anything -- simply per each row define ComboBoxItem and put any control you like. In effect you will get multiple controls for the same data.
At this point the only missing part is selecting the mode. Since I no longer rely on manually switching visibility of the controls (combobox does it automatically) then I can bind to SelectedIndex and convert it only fly back and forth to mode.
Please note combobox is not bound per se to the actual data (angle in this case).

Related

Multiple combo boxes bound to same source with conditional visibility on items

Unlike many questions related to this, I'm not having an issue with all combo box values being changed at when changing one combo box selection.
My problem is that I want to change the visibility of certain items when they are selected in the other list. I have two input port combo boxes and when I select port 5, say, on the first one, I want port 5 to not appear in the drop down for the second combo box.
I've tried this solution How to set combox item visibility? as it looked very promising but it won't let me cast from string to ComboBoxItem in the code-behind.
What else am I to do? I thought of creating a style in the XAML itself, but I can't quite figure out the conditions to use within the XAML and can't seem to find any topics over it. Lastly, I also have conditions in the setters for my input properties to check that the value the port is being set to is not the same as the other port, but it's not seeming to do anything for the view.
Are you using an ObservableCollection? This would allow for two way data binding whereas your UI will reflect the contents of each ObservableCollection in realtime if added to or removed from in an event. In another scenario, I had to apply a custom object to bind to in order to determine whether or not to show it, however, it was not the contents of a combobox, which are harder to access.

Always show filter cell editors in RadGridView - Telerik for WinForms

I am using a basic RadGridView to show some data in a WinForms application. I have set the RadGridView to EnableFiltering and that is working just peachy. I have also set the GridFilterCellElement to Collapse both the filter icon, and the filter cell text that says "Contains:", and "Equals:", etc. The filter cells essentially look like empty grey cells right now, until one of them gets focus... at which point in time the proper editor fills the cell. I am setting the visibility of the filter icon and the filter cell text in the ViewCellFormatting handler of the RadGridView.
What I want to know, is how can I just make the editors for the entire row of filter cells, just show by default? In other words, I just want to show the editors in the filter cells at all times so it is completely obvious that the user can filter the data with the editing controls above.
I thought this was going to be very easy, but it has proven to be quite tricky. Any help would be greatly appreciated.
I would suggest against showing the editors at all times, despite the fact it will not be a trivial task, there is a reason for the editors to work the way they do.
Editors basically consist of some controls in them - being text box, drop down list, date picker etc. Controls, as we know are not lightweight objects (having plenty of controls shown will have significant performance impact) and do have some limitations e.g. they don't support clipping.
As RadGridView uses virtualization for its cells, cell elements are being reused during operations like scrolling, filtering, etc. Cell elements are much more flexible and overcome the limitations that Controls introduce and also, they are lightweight elements, as opposed to controls, which provides great performance, hence the grid can display plenty of data.
I hope I managed to explain why I don’t think this is a good idea.
The elements - icon and text, that you have hidden, are there precisely to show the user that these are filter cells.
If you need faster input, you can perhaps open the editor automatically (using CurrentCellChanged and BEginEdit method) when the user clicks on it.

WPF App with responsive design

I want to make a WPF app which has a different position of its controls depending on the size of the window.
If MainWindow has Width above, let's say 500, then I want my Grid to be 2x2, and if it's below 500, then 4x1 (4 Rows, 1 Column).
First I made 2 Grids, one 2x2, the other 4x1. I have 4 different UserControls, which represent View part of the MVVM. I thought I'd use VisualStateManager with 1 group, which has 2 states, one for defaultGrid, the other for narrowGrid. First state sets Visibility of the first Grid to Visible, and the second to Collapsed, and the other state reversed (Do I even need them both to do that?). I put GoToElementState in the handler for SizeChanged event. I saw this in a book, but they didn't use UserControls, instead they just copied all the controls from the first Grid into the second one and changed the Row and Column properties for each control. I thought that it's possible for 2 different Grids to share 1 UserControl (that was actually the only reason why I put a dozen or so controls/elements in those 4 UserControls in the first place), but so far I've found that that's not possible (although I could be wrong here).
Now, for some controls I guess I don't mind that I technically have 2 instances of each UserControl, because the bindings make them synchronized, but if I type something in the TextBox and change the window size/visual state, then in "that same" TextBox I have different text.
I've come to the conclusion that I don't need VSM at all and that I don't need any other Grids besides the root Grid. In the handler for SizeChanged I've made rootGrid be either 2x2 or 4x1, depending on the window width. In MainWindow.xaml.cs I've also made those 4 UserControls private fields and instantiated them. They are changing their Row and Column properties according to window width. By doing that I now always have only those 4 UserControl instances, that just change their position in the app. (I don't need multiple instances of any of those UserControls).
What I want to know is: Is there any better/more elegant/possibly conventional way of doing this, that I haven't found?
I had the idea of making just 2 UserControls (2 Views) and using VSM to represent them. Both Views would bind to the same properties of the ViewModel. "Synchronization" of inserted text in the TextBox or selected item of a ComboBox would then be done, for TextBox for instance, by binding the Text property of a TextBox, of the first View, to the Text property of a TextBox of the second View. But this doesn't seem like a better alternative.
I also had the idea of making custom converters for Row and Column bindings of UserControls, but that seemed even worse.
Btw. I'm using C#, VS 2013 and Windows 7. I know UWP have interesting stuff with AdaptiveTriggers in VSM, but I haven't switched to UWP yet, I just started playing with WPF a month ago.
Also I can't use WrapPanel because I need these controls in exactly 2x2 or 4x1 grids. And I can't use UniformGrid because I need them in specific order.
Any input on this would be appreciated.

Extremely slow performance with multiple user controls

I've put together a scheduling application similar in style to that found in outlook, however it can show the schedules of multiple people. I have written a user control, basically a Border with gradient filled background & TextBlock. One of these controls are added to a Canvas at a set location for every appointment. The trouble is, I will have multiple users, with multiple appointments and may need to display 1000 or so appointments at a time. Initially, it takes an absolute age to instantiate all of these objects, however, I can live with this.
Unfortunately, the big problem arises when I try to scroll through the appointments. I have a couple of buttons to scroll left and right and upon clicking these, the UserControls' Left position are moved left or right a certain number of pixels - it can take several seconds between clicking a button and repainting(I also tried with labels just to test, but it was the same).
I guess the real question here is how to implement an interface, showing hundreds of controls with adequate performance and if this isn't achievable, how would I approach such an UI.
One possible option is a TextBlock CustomControl. You can get the exact same style as you have in your usercontrol but with a somewhat faster loading time.
Without a good, minimal, complete code example that reliably reproduces the problem, it will be difficult if not impossible to completely understand the performance problem you are having, never mind provide a solution.
That said, from your description it sounds like you are really looking to present the user with some type of ItemsControl, such as ListBox or ListView (a specialization of ListBox). In an ItemsControl, you can specify an ItemTemplate that defines how each item in the list will appear; this is analogous to the UserControl you apparently are using now.
I believe it's likely it will work fine just with that change alone. I.e. define your per-item visual as a DataTemplate instead of a UserControl, and set the ItemTemplate property of e.g. your ListBox to that template, then just bind your collection of appointment objects to the ListBox.ItemsSource property.
Note that the ListBox class already defaults to using VirtualizingStackPanel in its ItemsPanel template. So you should have no performance problems at all with this approach if you use ListBox.
If you want to use a different ItemsControl or create a custom one, you may or may not find that you need to use a virtualizing panel object explicitly (such as the VirtualizingStackPanel that ListBox uses). With just 1000 items in the list, even a non-virtualized panel may be fine, but if not then even when not using ListBox, you can always specify it explicitly.

wpf listbox with < 10k entries... how do i make it effiecient?

iphone has 10 listbox entries at a time, it doesnt' load all 10k entries and scroll them all at the same time. it adds one entry, and subtracts one entry at a time. so how do you do this in a wpf listbox? how do i make, say 20 listbox entries, and add one or two, and subtract the same amount? does data binding the listbox take care of this performance issue?
What you are looking for is the VirtualizingStackPanel. This control will only display the items you actually need on screen, even if you have thousands more that are available to the item. Here is the MSDN article about it:
http://msdn.microsoft.com/en-us/library/system.windows.controls.virtualizingstackpanel.aspx
Here is a small article about this control that explains it simply:
http://windowsclient.net/blogs/microsoft_kc/archive/2009/05/13/what-is-virtualizing-stackpanel.aspx
One key point in this second article is that you should use the Recycling property to make sure you use the least amount of resources like so:
VirtualizingStackPanel.VirtualizationMode="Recycling"
The ListBox WPF control uses a VirtualizingStackPanel by default, unless you change the ScrollViewer.CanContentScroll property false, in which case you get smooth scrolling in exchange for a loss of virtualization.

Categories