简体   繁体   中英

SelectedItem has been changed when show view

I am going to create a ComboBox with availability of add item manually by user in WPF. So I have created some code like this:

My View code:

<ComboBox SelectedItem="{Binding Path=SelectedItem}" ItemsSource="{Binding ItemsSource}" Text="{Binding Path=InputText, UpdateSourceTrigger=LostFocus}" IsEditable="True"/>

My ViewModel code:

public class ViewModel : INotifyPropertyChanged
{
    private string selectedIndex;
    private string inputText;
    public event PropertyChangedEventHandler PropertyChanged;

    public string InputText
    {
        get { return inputText; }
        set { inputText = value;  OnPropertyChanged(); CheckAndInsertIfValid(); }
    }

    public string SelectedItem
    {
        get { return selectedIndex; }
        set { selectedIndex = value; OnPropertyChanged(); }
    }

    public ObservableCollection<string> ItemsSource { get; set; }

    public ViewModel()
    {
        ItemsSource = new ObservableCollection<string>()
        {
            "0", "1", "2", "3", "4" ,"5"
        };
        SelectedItem = ItemsSource[3];
    }

    public virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private void CheckAndInsertIfValid()
    {
        if (InputText != "Some Values" && !ItemsSource.Contains(InputText))
            ItemsSource.Add(InputText);
    }

}

It works fine and user can add to ComboBox manually. But when view is showing to user SelectedItem will be "null" however I've set.

I don't know why SelectedItem is going to be null? And How can I prevent to change of SelectedItem?

The InputText property in your case doesn't seem necessary to me, you can get rid of it and bind directly to the SelectedItem property:

<ComboBox SelectedItem="{Binding Path=SelectedItem}" ItemsSource="{Binding ItemsSource,Mode=TwoWay}" Text="{Binding Path=SelectedItem, UpdateSourceTrigger=LostFocus}" IsEditable="True"/>

And change your VM accourdingly:

 public class ViewModel : INotifyPropertyChanged
{
    private string _selectedItem;        
    public event PropertyChangedEventHandler PropertyChanged;

    public string SelectedItem
    {
        get { return _selectedItem; }
        set { _selectedItem = value; OnPropertyChanged(); CheckAndInsertIfValid(); }
    }

    public ObservableCollection<string> ItemsSource { get; set; }

    public ViewModel()
    {
        ItemsSource = new ObservableCollection<string>()
        {
            "0", "1", "2", "3", "4" ,"5"
        };
        SelectedItem = ItemsSource[3];
    }

    public virtual void OnPropertyChanged([CallerMemberName]string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private void CheckAndInsertIfValid()
    {
        if (SelectedItem != "Some Values" && !ItemsSource.Contains(SelectedItem))
            ItemsSource.Add(SelectedItem);
    }

}

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