Silverlight, resetting AutoCompleteBox.SelectedItem to null - silverlight-4.0

I have a problem with AutoCompleteBox. I wanted to use it as editable combobox. So I created custom control inheriting from AutoCompletBox and added two dependency properties named as SelectedValue (for binding to DataContext) and SelectedValuePath. When user selects an item, my custom control updates SelectedValue as the following way:
string propertyPath = this.SelectedValuePath;
PropertyInfo propertyInfo = this.SelectedItem.GetType().GetProperty(propertyPath);
object propertyValue = propertyInfo.GetValue(this.SelectedItem, null);
this.SelectedValue = propertyValue;
It works.
Reversely, when underlying datacontext changed, SelectedValue is also changed; so custom control's SelectedItem also has to change:
if (this.SelectedValue == null)
{
this.SelectedItem = null; //Here's the problem!!!
}
else
{
object selectedValue = this.SelectedValue;
string propertyPath = this.SelectedValuePath;
if (selectedValue != null && !(string.IsNullOrEmpty(propertyPath)))
{
foreach (object item in this.ItemsSource)
{
PropertyInfo propertyInfo = item.GetType().GetProperty(propertyPath);
if (propertyInfo.GetValue(item, null).Equals(selectedValue))
this.SelectedItem = item;
}
}
}
What troubles me is when SelectedValue is null. Even if SelectedItem is set to null, Text property is not cleared, if it was manually edited by user. So SelectedItem = null but AutoCompleteBox displays a text entered manually. Can someone show me right way of resetting AutoCompleteBox.SelectedItem property?

What a coincidence... I was just doing the same thing today. In fact don't even bother to set SelectedItem = null. You can just set Text = String.Empty and both the text area and the SelectedItem will be cleared.

That doesn't work in an MVVM set up

It is solve the problem:
selectedChange += (e,v) => {if (selected item == null) Text = String.Empty};
but it couse to other problem - when you select item, and insert later...

Related

In UWP, how to skip tab key navigation for an UserControl and all of its child element?

In UWP, I want to handle and skip the tab key navigation for particular set of controls dynamically.
For e.g., I've two user controls (Both have lot of children which will be added dynamically) in my main page and want to skip tab key navigation for one usercontrol dynamically on specific scenario for a moment.
So I've tried to set "IsTabStop" as false to that UserControl. But which is not effective on its child controls. Still tab key focus moved inside the children of that UserControl.
Note: If I set "IsEnabled" as false, then its working. But I don't want to use because it affects Visual appearance.
Thanks in advance.
There is no IsTabStop property in StackPanel class. The IsTabStop property is defined in Windows.UI.Xaml.Controls.Control class, and the StackPanel class is not inherited from Control class, either directly or indirectly. You can not use IsTabStop property to set a StackPanel instance.
Therefore, if you want to skip tab key navigation for one stackpanel, you need to set the IsTabStop property to False in each control in the stackpanel.
Update:
By testing, the child elements in a UserControl can not inherit the value of IsTabStop property. Therefore, you cannot skip tab key navigation for all the child elements in a UserControl by setting the IsTabStop property to False.
You could use a method defind in your UserControl class to set IsTabStop to false for every item in your UserControl.
For example:
MyUserControl.cs
public void SetIsTabStop(bool flag)
{
var result = VisualTreeFindAll<Control>(this);
foreach (var item in result)
{
item.IsTabStop=flag;
}
}
private IList<T> VisualTreeFindAll<T>(DependencyObject element)
where T : DependencyObject
{
List<T> retValues = new List<T>();
var childrenCount = VisualTreeHelper.GetChildrenCount(element);
for (var i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(element, i);
var type = child as T;
if (type != null)
{
retValues.Add(type);
}
retValues.AddRange(VisualTreeFindAll<T>(child));
}
return retValues;
}
Use the name of a UserControl instance to call the SetIsTabStop(bool flag) method with False.
userControlName.SetIsTabStop(false);
Update:
Maybe you could try the following workaround.
Add the KeyDown event handler for the UserControl in your Page.
private void UserControl_KeyDown (object sender, KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Tab)
{
e.Handled = true;
button1.Focus(FocusState.Keyboard);
}
}
You need to let the first control except the UserControl and all its child controls get the focus, then the key navigation will skip the child controls in the UserControl except the first child control in the UserControl.

windows phone Binding to two property

I have a Button, and I want the button to be visible only when Condition A == true and Condition B == true.
Now, my viewModel already have two Property whose return type is boolean.
So is it possible to achieve it with XAML Binding?
If you want your button to be visible depending on two properties then in this case it would be better you make a Visibility Property in your Viewmodel and bind that property to Button Visibility Property in Xaml.
For example :-
In Viewmodel create Visibility property -
private Visibility _visBtn = Visibility.Collapsed;
public Visibility VisBtn
{
get { return _visBtn ; }
set
{
_visBtn = value;
RaisePropertyChanged("VisBtn "); // INotifyPropertyChanged Implemented
}
}
You have to just set this property according to your logic. like :-
If(Condition A == true && Condition B == true)
VisBtn = Visibility.Visible;
Now Bind this property to Button In Xaml Like -
<Button Content="My Button" Visibility="{Binding VisBtn }" />
Note :- Make sure that you have implemented INotifyPropertyChanged In your Viewmodel and Your Xaml Page DataContext is set to corresponding Viewmodel properly.
Second Case :-
If you want to set your button Visibility on basis of single bool property then you can implement BooleanToVisibility Converter this converter map Boolean property to Visibility type.
Then How to implement boolean to visibility Converter help you.

Silverlight 4 AutoCompleteBox, setting SelectedItem to null

In the source code of AutoCompleteBox (downloadable from Microsoft) I found the following:
/// <summary>
/// Called when the selected item is changed, updates the text value
/// that is displayed in the text box part.
/// </summary>
/// <param name="newItem">The new item.</param>
private void OnSelectedItemChanged(object newItem)
{
string text;
if (newItem == null)
{
text = SearchText;
}
else
{
text = FormatValue(newItem, true);
}
// Update the Text property and the TextBox values
UpdateTextValue(text);
// Move the caret to the end of the text box
if (TextBox != null && Text != null)
{
TextBox.SelectionStart = Text.Length;
}
}
What troubles me is {text = SearchText;} line. If I bind SelectedItem to my ViewModel and after a search entry into the AutoCompleteBox, SearchText is not empty, then when underlying data is reset to null, AutoCompleteBox may display SearchText instead of empty string. Can someone explain why it is written this way, and suggest a workaround?
I believe that's so that when there is no actual search item, the box displays something like "Search Here". For an example, see StackOverflow's search box, which says "search" when it is empty.
This is really annoying and I've yet to find a fix. It is on the Silverlight Toolkit issue tracker here. I've also read something here about setting the ItemsSource to null that I'm going to play about with.
I'll update if I find a workaround.

Listbox selectedindex property change doesn't update the UI

Using javascript, I am trying to change the selection of the listbox item like this:
function selectFirstActiveListItem(oListBox)
{
for (var i = 0; i < oListBox.options.length; i++)
{
oListBox.selectedIndex = i;
var szStatus = GetDomboBoxItemAttribute("Status", m_pdocConnectType.getXMLDOM(), oListBox);
if ("Enabled" == szStatus)
return;
}
oListBox.selectedIndex = 0;
}
Though the index correctly changes at the background, but it is not reflected on the UI. The listbox still shows the old selection.
What's going wrong?
try this instead:
oListBox.options[i].selected = true;
Oops! That was working and showing the correct result. My take on the behavior was incorrect there.

Selected ListItem in Datasource not Selected after DataBinding

I'm selecting a ListItem as I add it to a ListItemCollection. Then I use that ListItemCollection as a datasource for a DropDownlist but the Selected List Item is not being selected after databind. Here is an example of the code:
ListItemCollection items = new ListItemCollection();
ListItem item;
item = new ListItem("Option 1", "1");
items.Add(item);
item = new ListItem("Option 2", "2");
item.Selected = true;
items.Add(item);
ddl1.DataSource = items;
ddl1.DataBind();
I'm trying to get this to work so I can return only a list of items, instead of a list of items and the selected value. Is there a way to make the DropDownList select the selected ListItem from the ListItemCollection (or any other type of collection)?
Hmm... this seems like a strange method to take for accomplishing this, you should be able to do something along these lines:
ddl1.Items.Clear();
foreach(ListItem item in items)
{
ddl1.Items.Add(item);
}
Which should solve your selection issue...
I don't think you can set the selected value before you bind to the drop down. I think you have to do it after it has been bound.
Just set the SelectedValue property of your DropDownList :
ddl1.SelectedValue = "Option 2";
Here I'm using a literal string, but it's best to the item.Text value to set it. You can use it before or after the DataBind(), it works either way.