3
votes

In a MVVM Silverlight application the user can enter text in the TextBox and the ListBox contents changes accordingly. E.g.: If the user enter "TV" the ListBox will populate all the available Television brands and the user can select a product from the ListBox and ListBox entries; next if he enters "computer" ListBox contents change and populate with ComputerNames.

As soon as the user types something it searches in a dictionary with values matching key.

View:

<TextBox Name="SearchTBox" Text="{Binding SearchStr,UpdateSourceTrigger=PropertyChanged}" />
<ListBox Name="AnalysisLBox" ItemsSource="{Binding DataList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"   
         SelectedItem="{Binding UserSelectedItem,Mode=TwoWay}"                                   
         Width="250" BorderBrush="Transparent" SelectedIndex="{Binding LBoxSelectedIndex,Mode=TwoWay}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding}" />
            </StackPanel>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

ViewModel:

SortedDictionary Data()
{
    List<string> tvList = new List<string>() { "Sony", "SamSung", "LG","Sharp" };
    List<string> computerList = new List<string>() { "HP","Dell","Lenovo","Gateway" };
    List<string> cameraList = new List<string>() { "Nikon","Sony","Panasonic" };
    SortedDictionary<string, List<string>> Data = new SortedDictionary<string, List<string>>();
    Data.Add("TV", billingList);
    Data.Add("Computer", salesOutList);
    Data.Add("Camera", customerAllocationList);
}

ObservableCollection<string> dataList = new ObservableCollection<string>();
public ObservableCollection<string> DataList
{
    get { return dataList ; }
    set { dataList = value; NotifyPropertyChanged("DataList"); }
}

int lBoxSelectedIndex;
public int LBoxSelectedIndex
{
    get { return lBoxSelectedIndex; }
    set { lBoxSelectedIndex = value; NotifyPropertyChanged("LBoxSelectedIndex"); }
}

string userSelectedItem;
public string UserSelectedItem
{
    get { return userSelectedItem; }
    set
    {
        userSelectedItem = value;
    dataList.Clear(); 
        LBoxSelectedIndex =-1;
        NotifyPropertyChanged("UserSelectedItem");
    }
 }

As soon as a key matches user typed string ('TV') it populates an ObservableCollection<string> dataList with tvList which is bound to the ListBox. The user types Camera, it clears the dataList and adds cameraList. The problem occurs here. The listBox's selection is not cleared when it clears data and populates with new data. The same item at the previously selected location remain selected. I tried to set the SelectedIndex to -1 from the UserSelectedItem Property of the ViewModel but it didn't work.

2
I don't get it, you want to clear the listbox when the listbox selection changes?Shawn Kendrot
Clear the listbox as soon as the user select an item from the list box.Prathibha

2 Answers

2
votes

You can also set userSelectedItem=null in

ObservableCollection<string> dataList = new ObservableCollection<string>();
public ObservableCollection<string> DataList
{
    get { return dataList ; }
    set 
    { 
        dataList = value;
        userSelectedItem=null
        LBoxSelectedIndex = -1;
        NotifyPropertyChanged("DataList"); 
    }
 }
2
votes

I think you may have your properties confused. When a selection is made in the ListBox, the UserSelectedItem setter is triggered and clears the dataList and sets the LBoxSelectedIndex to -1. So really what happens when a user selects an item from the ListBox is the ListBox is cleared and nothing is selected.

Instead, it seems you should be clearing the selection when the DataList is changed.

string userSelectedItem;
public string UserSelectedItem
{
    get { return userSelectedItem; }
    set
    {
        userSelectedItem = value;
        NotifyPropertyChanged("UserSelectedItem");
    }
}

ObservableCollection<string> dataList = new ObservableCollection<string>();
public ObservableCollection<string> DataList
{
    get { return dataList ; }
    set 
    { 
        dataList = value;
        LBoxSelectedIndex = -1;
        NotifyPropertyChanged("DataList"); 
    }
 }

You'll also need to clear the DataList when SearchStr is updated and it does not equal any of the keys in the the sorted dictionary.

string searchStr;
public string SearchStr
{
    get { return searchStr; }
    set
    {
        searchStr = value;
        LBoxSelectedIndex = -1;
        if (string.IsNullOrEmpty(searchStr))
            DataList = null;
        else
        {
            List<string> selectedValue;
            if (Data.TryGetValue(searchStr, out selectedValue))
                DataList = new ObservableCollection<string>(selectedValue);
            else
                DataList = null;
        }
        NotifyPropertyChanged("SearchStr");
    }
}