views:

270

answers:

1

Hello,

Sorry for the earlier lengthy post. Here is my concise (!) description.

I bind a collection view to a combobox as a itemsSource and also bind its selectedvalue with a property from my view model. I must keep IsSynchronizedWithCurrentItem="False".

I change the source list ofr the view and then refresh the view. The changed (added, removed, edited) items appear correctly in the item list of the combo. But problem is with the selected item. When I change its property which is also the displaymember path of the combo, the changed property value does not reflect back on the selecton box of the combo. If you open the combo dropdown it appears correctly on the item list but not on the selection box.

Now if I change the combobox tag to Listbox in my XAML (keeping all attributes as it is) then when selected item's displaymember property value is updated, the changes reflect back on the selected item of the list box .

Why this issue?

Just FYI:

  1. My View Model has properties EmployeeCollectionView and SelectedEmployeeId which are bound to combo as ItemsSource and SelectedValue resp. This VM implements the INotifyPropertyChanged interface.

  2. My core employee class (list of which is the source for the EmployeeCollectionView) is simply a Model class without INotifyPropertyChanged.

  3. DisplayMemberPath is "Name" property of employee Model class. I change this by some means and expect the combo selection box to update the value.

  4. I tried refreshing ther SelectedEmployeeId by setting it 0 (where it correctly selects the dummy "-- Select All --" employee entry from itemsSource) and old selected value back. But no use. The old value takes me back to the old label. Items collection has latest entry though.

  5. When I make combobox's IsEditable=True before the view's refresh and after refresh I make IsEditable=False then the things work out correctly!

But this is a patch and is unnecessary.

Thx

Vinit Sankhe

A: 

Your points #2 and #3 are why this isn't working. When the ComboBox has an item selected, it displays in the box the Employee.Name property. You state in #2 that Employee does not implement INotifyPropertyChanged and in #3 you are changing Name and expecting it to update in the ComboBox. But the ComboBox has no idea that the property changed so its displayed value will not change.

I've put together a very simple example that will demonstrate. If you comment out the PropertyChanged event you'll notice that clicking the button no longer has an effect on the UI.

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        SizeToContent="WidthAndHeight">
    <StackPanel>
        <ComboBox ItemsSource="{Binding}" DisplayMemberPath="Name" SelectedIndex="0" Width="150" Height="25" />
        <Button Content="Change" Width="75" Height="25" Click="button_Click"/>
    </StackPanel>
</Window>

And the code behind...

public partial class MainWindow : Window
{

    private ObservableCollection<Thing> things;
    private Queue<string> words;

    public MainWindow()
    {

        // some dummy data
        string text = "Lorem ipsum dolor sit amet consetetur sadipscing elitr sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat sed diam voluptua";
        words = new Queue<string>(text.Split(' '));

        things = new ObservableCollection<Thing>();
        things.Add(new Thing { Name = words.Dequeue() });
        things.Add(new Thing { Name = words.Dequeue() });
        things.Add(new Thing { Name = words.Dequeue() });

        DataContext = things;

        InitializeComponent();

    }

    private void button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        things[0].Name = words.Dequeue();
    }

}
Josh Einstein
Hi Josh,Thx for ther answer but then why does this work for a ListBox. The selected item of the ListBox correctly shows the updated Name (without the INotify Interface).As far as I know, in MVVM the core model classes (employee class in my case) are not advised to have a INotifyPropertyChanged. only ViewModels implement this interface.
Vinit Sankhe
Without seeing the code, it's hard for me to tell why ListBox works. But your understanding of MVVM is not necessarily incorrect, but MVVM is still relatively new and there aren't really any hard and fast rules. The fact is, in MVVM you aren't supposed to expose a "model" class directly in the UI but everyone breaks that rule from time to time. But if you want changes to bound members to be reflected in the UI, you *have* to implement INotifyPropertyChanged.
Josh Einstein