Andre
Andre

Reputation: 774

Silverlight SelectedIndex not Databinding Correctly

I have unique behavior that I want to do.

I have a combobox that is databound to list of viewmodel items. The first item is "[ Select Item ]". The expected behavior is, as the user selects an item, I will do something, then reset the index back to the first item.

This works, except for the fact that if you want to select the 3rd item, 2 times in a row. Here is code: ItemViewModel:

// NOTE, I have all the INotify goo actually implemented, this is the shorthand
// without goo to make it more readable.
public class ItemViewModel : INotifyPropertyChanged
{
  public string Caption { get; set; }
  public string Test { get; set; }
}

ViewModel: (all my properties call OnPropertyChanged in the set as appropriate)

public class ViewModel : INotifyPropertyChanged
{
  public ObservableCollection<ItemViewModel> ChildItems { get; set; }
  public int SelectedChildIndex { get; set; }
  public string DebugOutText { get; set; }

  public ViewModel()
  {
    ChildItems = new ObservableCollection<ItemViewModel>();
    SelectedChildIndex = -1;
    DebugOutText = string.Empty;
  }
  public void LoadChildItems()
  {
    ChildItems.Add(new ItemViewModel { Caption = "[ Select Item ]" });
    ChildItems.Add(new ItemViewModel { Caption = "One", Test = "Item 1" });
    ChildItems.Add(new ItemViewModel { Caption = "Two", Test = "Item 2" });
    ChildItems.Add(new ItemViewModel { Caption = "Three", Test = "Item 3" });
    SelectedChildIndex = 0;
  }
  private void OnPropertyChanged(string propName)
  {
    if (propName == "SelectedChildIndex") { this.OnSelectedChildIndexChanged(); }
    if (this.PropertyChanged != null)
    { this.PropertyChanged(this, new PropertyChangedEventArgs(propName)); }
  }
  public void OnSelectedChildIndexChanged()
  {
    if (SelectedChildIndex <= 0) return;
    DebugOutText += "\r\n" + ChildItems[SelectedChildIndex].Test;
    SelectedChildIndex = 0; // <- BIG ISSUE HERE
  }
}

Now my xaml:

<StackPanel HorizontalAlignment="Left">
  <ComboBox Width="200" x:Name="combo"
            ItemsSource="{Binding Path=ChildItems}"
            SelectedIndex="{Binding Path=SelectedChildIndex, Mode=TwoWay}"
            DisplayMemberPath="Caption" />
  <TextBlock Text="{Binding Path=DebugOutText}"/>
</StackPanel>

Finally my App Startup:

var vm = new ViewModel();
vm.LoadChildItems();
this.RootVisual = new MainPage { DataContext = vm };

Repo steps are:

I've gone and put some trace code, the combo's SelectedIndex is 0, the ViewModel.SelectedChildIndex is 0, but the combo's SelectionChanged will not fire, unless I select something else.

I'm not really sure how to get it to work. Any help will be appreciated.

Upvotes: 1

Views: 235

Answers (2)

Luke Woodward
Luke Woodward

Reputation: 64949

I have to admit I have my doubts about to the usability of the behaviour you want. Nonetheless, if you have to use a combobox for this purpose, try replacing the line

    SelectedChildIndex = 0;

with

    Deployment.Current.Dispatcher.BeginInvoke(() => SelectedChildIndex = 0);

Upvotes: 1

Phil Sandler
Phil Sandler

Reputation: 28016

Going to take a wild guess here. :)

// NOTE, I have all the INotify goo actually implemented, this is the shorthand 
// without goo to make it more readable.

You do not show your implementation of INotifyPropertyChanged. Most implementations do something like:

public int SelectedChildIndex 
{
    get
    {
        return _selectedChildIndex;
    }
    set
    {
        if (value == _selectedChildIndex) return;
        _selectedChildIndex= value;
        OnProperyChanged("SelectedChildIndex ");
    }
}

Which short circuits the notification if the property value doesn't change. If your code looks like this, take out the "if" statement and see if that fixes it.

Upvotes: 0

Related Questions