简体   繁体   中英

Trouble in binding ListView.SelectedItem

In my WPF mvvm(light) project I have such problem : after binding of ListView.SelectedItem to my ModelView , I'm trying to change it from ModelView .It seems to be ok, but nothing happend at View :

XAML :

<ListView SelectedItem="{Binding SelectedOne}" 
          ItemsSource="{Binding Items}">
</ListView>

<ListView     ScrollViewer.CanContentScroll="False"
              ItemsSource="{Binding Items}"
              ItemTemplateSelector="{StaticResource myDataTemplateSelector}"
              HorizontalContentAlignment="Stretch"
              SelectedItem="{Binding SelectedOne, Mode=TwoWay}"
              IsSynchronizedWithCurrentItem="True">
</ListView>

MOdelView :

ObservableCollection<ItemViewModel> _EAItems = new ObservableCollection<ItemViewModel>();
public ObservableObject _selectedOne;

public ObservableCollection<ItemViewModel> Items
        {
            get
            {
                return _EAItems;
            }
            set
            {
                _EAItems = value;
            }
        }

public ObservableObject SelectedOne 
        {
            get { return _selectedOne; }
            set 
            {

                if(_selectedOne != value)
                _selectedOne = value;

            }
        }
Select = new RelayCommand(() => 
            {
                if (qw == 15) { qw = 0; }else
                SelectedOne = Items[qw];
                qw++;
            });

Items is ObservableCollection .

I added another Listview and bind it to the same sources. When I change SelctedItem in one of Listview , it's displayed on another , vise versa.

I looked thru alot similar solutions, and I can't figure what is wrong :(

first you should also post the code for the binding for the ItemsSource, the ItemsSource property.

but the main problem is the you do not call PropertyChanged in your setter

    public ObservableObject SelectedOne 
    {
        get { return _selectedOne; }
        set 
        {

            if(_selectedOne != value)
            _selectedOne = value;

            OnPropertyChanged("SelectedOne ");//<-- otherwise the view dont know that the SelectedItem changed
        }
    }

In order to make the binding work you would have to raise a PropertyChanged event from the SelectedOne setter. The class that defines the SelectedOne property would have to implement INotifyPropertyChanged .

Regardless of the type of the SelectedOne property (even if it is itself an ObservableObject), you have to raise a PropertyChanged event when the value of the property changes.

I agree with Clemens and blindmeis. The only fact is that the SelectedOne need to be the same class that the one set for the Collection. And with the MVVM-light libraries, the method is RaisePropertyChanged instead of OnPropertyChanged (if your viewModel inherit from ViewModelBase).

If your source contains ItemViewModels should use this code :

private ItemViewModel _selectedOne;

public ItemViewModel SelectedOne 
{
    get { return _selectedOne; }
    set 
    {

        if(_selectedOne != value)
        _selectedOne = value;

        RaisePropertyChanged("SelectedOne");
    }
}

The reason why your collection don't need RaisePropertyChanged is that ObsvervableCollection class already contains it in a certain way.

Regards,

Kévin

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM