Accessibility for Silverlight Combobox Items - silverlight

In my Silverlight page I have a combobox. In the code-behind I'm filling the combobox items like so:
this.ProblemList.Items.Add(Strings.Review_SelectProblem);
this.ProblemList.Items.Add(Strings.Review_IncorrectCharacters);
this.ProblemList.Items.Add(Strings.Review_MissingText);
...
this.ProblemList.SelectedIndex = 0; //Set the default selection
Elsewhere, in my XAML page I am providing accessibility (for the disabled) to other non-combobox controls by doing this:
AutomationProperties.Name="{Binding Strings.Review_Access_ParagraphCorrect}"
I'd like to provide Accessibility to my combobox items but the only way I've been able to find is like so:
AutomationProperties.SetLabeledBy(this.nameInput, this.nameLabel);
The problem with this is that my combobox items must have a name. How do I assign a name to my combobox items programmaticly or how can I provide accessibility in the code behind with out referencing the name of the combobox items?
Thank you for your help,
Aaron

You can try to use something like this:
ComboBoxItem tmpItem = new ComboBoxItem();
tmpItem.Content = Strings.Review_SelectProblem;
tmpItem.Name = Strings.Review_SelectProblem;
this.ProblemList.Items.Add(tmpItem);
I hope I understood you correctly.

Related

Set VisualState of combobox when a item is selected in Xaml (Silverlight)

When my combobox expands and I select an item, I want the combobox to change visual state(it is highlighted). This will signify something is selected. I tried various VisualStates but none of them would trigger in this scenario. How can I achieve this? Thanks.
The standard ComboBox simply doesn't have states to distinguish between having something selected and having nothing selected.
There are a number of ways to go about solving the underlying problem, and it depends mostly on the answer to the following question:
Do you really need to change the visual appearance of the ComboBox itself or does it suffice to style the selected item more prominently?
If it's the latter, you're best served with the rather easy way of using a custom control template for the ComboBoxItems.
If you really want to style the ComboBox itself that way, there are two options I can think of:
A) Add custom states to a ComboBox with a custom template.
Copy your ComboBox's control template and add another state group to the already present states. Both of this is typically done in Expression Blend.
After that you can update the new states in code with
VisualStateManager.GoToState(this, "Selected", true);
for example. You will have to set those states yourself when the first item is chosen. This could be done on the SelectionChanged event.
B) Derive from ComboBox
If you want to use the control in this way often, it might be worthwhile to derive from ComboBox to make your own custom control.
It would look somthing like this:
[TemplateVisualState(Name = "SelectedStates", GroupName = "Unselected")]
[TemplateVisualState(Name = "SelectedStates", GroupName = "Selected")]
// ... (more attributes copied from the ComboBox ones)
public class MyComboBox : ComboBox
{
public MyComboBox()
{
SelectionChanged += HandleSelectionChanged;
DefaultStyleKey = typeof(MyComboBox);
}
void HandleSelectionChanged(object sender, SelectionChangedEventArgs e)
{
VisualStateManager.GoToState(this, SelectedItem != null ? "Selected" : "Unselected", true);
}
}
And you would then need a default style based on the default ComboBox style (or whatever you usually use).
Note that I didn't test this in any way.

ListView Items sorting?

I have a ListView which contains four column, In which i am adding items dynamically as :
ListViewItem lvi = new ListViewItem();
lvi.Background = ... color you want ... ;
lvi.Content = new {Server = "test1", .... };
listViewResult.Items.Add(lvi);
Now I want to sort this dynamically generated ListView on a perticular column click.
How can I achieve this?
I found article here which explain the custom sorting.
VirtualizingStackPanel.IsVirtualizing=”True”
First you need to specify the above property to true in your ListView, (this is the default value for ListView in WPF).
Then next, you need to use custom sorter, instead of SortDescriptions as described in my earlier blog. The key is using the CustomSort property of ListCollectionView:
ListCollectionView view = (ListCollectionView)CollectionViewSource.GetDefaultView(myListView.ItemsSource);
Then in your ColumnHeader click event handler, you add something like the following:
view.CustomSort = sorter;
myListView.Items.Refresh();
Where sorter is a custom class you implement the IComparer interface.

WPF Accessing Items inside Listbox which has a UserControl as ItemTemplate

I have Window that has a ListBox
ListBox(MyListBox) has a DataTable for its DataContext
ListBox's ItemSource is : {Binding}
Listbox has a UserControl(MyUserControl) as DataTemplate
UserControl has RadioButtons and TextBoxes (At first They're filled with values from DataTable and then user can change them)
Window has one Submit Button
What I want to do is, when user clicks the submit button
For each ListBox Item, get the values form UserControl's TextBoxes and RadioButtons.
I was using that method for this job :
foreach(var element in MyListBox.Items)
{
var border = MyListBox.ItemContainerGenerator.ContainerFromItem(element)as FrameworkElement;
MyUserControl currentControl = VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(myBorder,0) as Border,0)as ContentPresenter,0)as MyUserControl;
//And use currentControl
}
I realised nothing when using 3-5 items in Listbox. But when I used much more items, I saw that "var border" gets "null" after some elements looped in foreach function.
I found the reason here :
ListView.ItemContainerGenerator.ContainerFromItem(item) return null after 20 items
So what can I do now? I want to access all items and get their values sitting on user controls.
Thanks
You should use objects who implement INotifyPropertyChanged and bind an ObservableCollection of it to the ItemSource
And then you can get all the list of items.
Here some quick links from MSDN to get more informations
How to: Implement Property Change Notification
Binding Sources Overview
You should google for some tutorials about this.
Zied's post is a solution for this problem. But I did the following for my project:
I realised that there's no need to use UserControl as DataTemplate in my project. So I removed ListBox's DataTemplate.
I removed MyListBox.DataContext = myDataTable and used this:
foreach(DataRow dr in myDataTable.Rows)
{
MyUserControl muc = new MyUserControl(dr);
myListBox.Items.Add(muc);
}
I took DataRow in my UserControl's constructor and did what I want.
And at last I could access my UserControls in ListBox by using :
foreach(MyUserControl muc in
myListBox)
{
//do what you want
}
Easy huh? :)

(WPF) Binding two classes to a control

I have two viewmodels. One which displays a collection of IPAddresses, and one which displays a collection of objects that has numerous parameters. One of these parameters is an IPAddress. So, I have another panel that binds to the properties of the second object. I would like a combobox to have the ItemSource set to the first object, but the selected item bound to the second object. However, I can only seem to set one datacontext on a control in code behind. Is there any way around this? I would prefer to do this all in code behind if possible (i find the xaml programming to be non-ideal at best), but I'll take anything.
For the ComboBox bind the collection of IPAddresses to the ItemsSource property, and bind the SelectedItem of the ComboBox to the IPAddress property of the SelectedItem of the collection of "numerous property objects".
This would be easier to answer if I had a better description of your objects including names. But it sounds to me like you should make a dictionary with the ipaddress as the key and the second object as the value.
If you can do that then you can bind to it in code like so:
comboBox.ItemsSource = dictionary;
comboBox.DisplayMemberPath = "Key";
comboBox.SelectedValuePath = "Value";
This is assuming that you have exactly one "second object" for every IPAddress in the collection. Which sounds about right given your description.
Take a look at the Source property of Bindings. It is basically a DataContext for a specific binding. It should make what you're trying to do very simple, especially in code behind.

In WPF, is it possible to have a combo box control, that looks like a RadioButton?

I have a whole bunch of code that is dependent on the ComboBox type, and I want to be able to use it on a new UI, but the UI that I want to use it for needs to look like a RadioButton for usability reasons. Is it possible to have a ComboBox control look like a set of RadioButtons?
My suggestion would be to use an ItemsControl with a DataTemplate that would render RadioButtons. To the ItemsControl you'd bind the same thing you're binding to the ComboBox.
One caveat is that you need to set the GroupName of the radio buttons to something that would be the same to the group, so they can be mutually exclusive. Otherwise, if you don't do anything, you'll be able to select more than one RadioButton simultaneously.
You could build a new UserControl that has many of the same methods that the ComboBox class does, but adapt it so that it creates multiple radio boxes instead.
Your question is kinda vague though.
IE create an Items collection on your user control, and when something is added, draw a radio box and resize your control, instead of what a combo box does and just adds a string to the list.
Then all you have to do is find and replace all your references to ComboBox with RadioIFiedComboBox.
Heres some comparison:
ComboBox cb = new ComboBox();
cb.Items.Add("blah");
or
RadioIFiedComboBox cb = new RadioIFiedComboBox();
cb.Items.Add("blah");
and
public class RadioIFiedComboBox : UserControl {
public ObservableCollection<object> Items = new ObservableCollection<object>();
public RadioIFiedComboBox() {
Items.CollectionChanged += new NotifyCollectionChangedEventHandler(YourCollectionChanged);
}
private void YourCollectionChanged(){
//do something here to redraw your controls
}
}
The code above is just an example, you'd have to create all the methods you use in the ComboBox class and create similar functionality.

Resources