Multiple choice on WinForms - winforms

What's the best way of implementing a multiple choice option in Windows Forms? I want to enforce a single selection from a list, starting with a default value.
It seems like a ComboBox would be a good choice, but is there a way to specify a non-blank default value?
I could just set it in the code at some appropriate initialisation point, but I feel like I'm missing something.

If you only want one answer from the group, then a RadioButton control would be your best fit or you could use the ComboBox if you will have a lot of options. To set a default value, just add the item to the ComboBox's collection and set the SelectedIndex or SelectedItem to that item.
Depending on how many options you are looking at, you can use a ListBox with the SelectionMode property set to MultiSimple, if it will be multiple choice or you could use the CheckBox control.

You should be able to just set the ComboBox.SelectedIndex property with what you want the default value to be.
http://msdn.microsoft.com/en-us/library/system.windows.forms.combobox.selectedindex.aspx

Use the ComboBox.SelectedItem or SelectedIndex property after the items have been inserted to select the default item.
You could also consider using RadioButton control to enforce selection of a single option.

You can use a ComboBox with the DropDownStyle property set to DropDownList and SelectedIndex to 0 (or whatever the default item is). This will force always having an item from the list selected. If you forget to do that, the user could just type something else into the edit box part - which would be bad :)

If you are giving the user a small list of choices then stick with the radio buttons. However, if you will want want to use the combo box for dynamic or long lists. Set the style to DropDownList.
private sub populateList( items as List(of UserChoices))
dim choices as UserChoices
dim defaultChoice as UserChoices
for each choice in items
cboList.items.add(choice)
'-- you could do user specific check or base it on some other
'---- setting to find the default choice here
if choice.state = _user.State or choice.state = _settings.defaultState then
defaultChoice = choice
end if
next
'-- you chould select the first one
if cboList.items.count > 0 then
cboList.SelectedItem = cboList.item(0)
end if
'-- continuation of hte default choice
cboList.SelectedItem = defaultChoice
end sub

Related

Keeping Focus/SelectedItem after DataGrid ItemsSource change

ive been working on this for a few days, but cant seem to come up with a solution
i have code on a timer that refreshes the DataGrid every few seconds
i tried many refresh options, but in the end they all lose the users focus and sometimes also the SelectedItem
heres my code:
AddHandler bw.RunWorkerCompleted, Function(sender As Object, e As ComponentModel.RunWorkerCompletedEventArgs)
Dim lst = e.Result
Dim lst2 = CType(lst, List(Of Object)).OfType(Of INotifyPropertyChanged)()
'If Items.Count = 0 Then
Dim a = SelectedItem
Collection.Clear()
Collection.AddRange(lst2)
SelectedItem = a
'ItemsSource = lst
'End If
'For Each rw In lst
' Dim mtch = Collection.Where(Function(x) x.GetHashCode = rw.GetHashCode)
'Next
i left the comments so you can see the different approaches i tried
RESULTS:
if i directly set the ItemsSource with the result (as in the comment), then the SelectedItem and the Keyboard.FocusedElement keep steady till the end of the above code, but somewhere between the end of this code and the next tick they are both turned into Nothing
if i go with the ObservableCollection then SelectedItem is lost as soon as i clear the collection and Keyboard.FocusedElement is only lost sometime between ticks. though the SelectedItem can be retained here with a temp backing variable
so the point is how do we refresh the items from the db while still keeping (most-importantly) the keyboard focus
and yes, i know that ObservableCollections are not "made" to be reset. in fact, im not really interested in using one. it just has one plus of keeping the SelectedItem
P.S. i also tried hooking into several events (OnItemsSourceChanged,SourceUpdated...) but they weren't fired at the right time, or didnt fire at all
any ideas?
id really most appreciate
thank you
You need to use the SelectedIndex instead of the SelectedItem property of the DataGrid. Save the selected index before replacing ItemsSource with lst.
The reason SelectedItem does not work is that this is a reference to an object in the list you are replacing.
Perhaps you don't want to use index because the focused item might move up or down based on database update. In that case you will need to use the key to find the index of the record in the new list.
If you can't use the index or don't have a key then I can't think of a good way to do this.
Also it seems to me that replacing the list completely will lead to other problems. If the user is typing something into DataGrid cell and you replace the list under them, they will lose their edits.
Your best option is the following:
When a user makes a selection, save the index or the current selecteditem in a variable.
in the CollectionChanged even in your collection re assign the selected item to whatever you saved before in the variable. The CollectionChanged event is triggered after any change in the collection so you will be able to do post processing which is in this case reassigning the selected item.
Have you verified that you have the same instance of the object? I.e. SelectedItem must exist in lst2. Otherwise you need to find the matching item in the new list and use that object instead.

Combox with fill-in option

I want to add to WPF Form a ComboBox which is bound to a datasource (in my viewmodel). But besides from the choices in my viewmodel I would also like to add the option of allowing a fill-in value.
How could I achieve something like that in XAML?
The first thing you need to do is turn on isEditable. I'm assuming that you also want to have the new value added to your datasource. If that is true then you will have to do some code since this is not possible with pure xaml. Here is an example of how to do this.

Can focus be remove from a control to modify its properties in VBA?

First I remove control visibility by doing this:
For Each ctl In Me.MySubform.Controls
ctl.Visible = False
Next ctl
and later, I go back and bind those controls I'm going to use for the current list of fields using an array of the caption and control source name.
For i = 0 To UBound(MyArray) Step 2
Me.MySubform.Controls(i).ControlSource = MyArray(i)
Me.MySubform.Controls(i + 1).Caption = MyArray(i + 1)
Me.MySubform.Controls(i).Visible = True
Me.MySubform.Controls(i + 1).Visible = True
Next i
The issue I run into is, if a user has clicked into one of these fields providing it with focus, I seem to set the control visible property to false or rebind the field to another field during the next refresh event.
I think by removing the controls focus I would be able to accomplish this; however, I have two concerns.
Is this possible in VBA (MS Access 2003)? If so how?
Is there a better more ideal way to accomplish this in this environment? If so, what options are available and what considerations go into picking a solution?
Thanks,
You cannot change the visible property of a control that has focus. Is this the problem? If so, it can be useful to keep a small control to receive focus with SetFocus : http://msdn.microsoft.com/en-us/library/aa205181(office.10).aspx

Set selection to newly added Item in WPF TreeView

I'm using a TreeView to let the user navigate a complex data structure more easily. I'm trying to add a feature to my application so my users can add new items to the datastucture by clicking a button on a toolbar. This new item has 3 levels, each with 1 item. I would like to select the item in the lowest level.
Adding the data isn't a problem, I just add a new item to the collection that is bound to the TreeView in a specific. I can lookup the item by hand browsing the TreeView, so I know the adding works. Now, I want to set the selection of the new item programmaticly. So the user can change the default settings in the element right away.
I've done some testing and I've found that setting the selection is done with something like:
var obj = TreeView.ItemContainerGenerator
.ContainerFromItem(selectedObject) as TreeViewItem;
obj.IsSelected = true;
I've tried adding this code directly after my Add-method. The adding function returns the new object and places this in selectedObject. The Add-method adds a to an ObservableCollection, which raises the appropriate events.
But, obj is always null directly after adding.
I've tried setting the selection in the LayoutUpdated event, but in this case the obj variable from the earlier code always null again.
I think I might be missing something here. Does anyone have an idea on how to add a new item to the bounded collection and select that item in the TreeView?
You might want to read this article by Josh Smith on using the treeview in WPF. He demonstrates how to use an IsSelected property that could easily be adapted for your needs, using the MVVM pattern.

Synchronised Comboboxes

How do I get 2 synchronized comboboxes so that changing the index of the one automatically changes the other one.
I have no idea what language you are using, but for something like .NET you would go into the SelectedIndexChanged event of the comboboxes and in there put:
Combobox1.SelectedIndex = ComboBox2.SelectedIndex and vice versa for the other one.
Note: You want to make sure that your boxes have the AutoPostback property set to True.
This depends on the framework/language/toolkit/platform, and many other features, but the basic idea is the same:
Just listen in for the "selected item changed" event/signal/etc on both combo boxes, and when one changes, set the other appropriately.

Resources