WPF MVVM ComboBox SelectedItem or SelectedValue not working

前端 未结 18 2217
一生所求
一生所求 2020-12-05 06:22

Update

After a bit of investigating. What seems to be the issue is that the SelectedValue/SelectedItem is occurring before the Item source is finis

相关标签:
18条回答
  • 2020-12-05 06:59

    You need to put the ItemsSource property BEFORE the SelectedItem property. I came across a blog a few days ago mentioning the issue.

    0 讨论(0)
  • 2020-12-05 06:59

    Use Loaded event:

    private void cmb_Loaded(object sender, RoutedEventArgs e) {
        if (cmb.Items.Count > 0) cmb.SelectedIndex = 0;          
    }
    

    It works for me.

    0 讨论(0)
  • 2020-12-05 07:01

    It could be the way you are applying the DataContext to the Page. In WPF, everytime you navigate to a Page everything gets re-initialized, constructor gets called, loaded methods, everything. so if you are setting your DataContext inside your View you will no doubt be blowing away that SelectedItem that the user selected. In order to avoid that use the KeepAlive property of your pages.

    <Page KeepAlive="True" ...>
       ...
    </Page>
    

    This will result in only the Loaded event being fired when navigating back to a page you have already visited. So you will need to ensure that you are setting the DataContext on Initialize (either externally or within the constructor) rather than Load.

    However, this will only work for that instance of the Page. If you navigate to a new instance of that page it constructor will be called again.

    0 讨论(0)
  • 2020-12-05 07:02

    In this case, the selecteditem bind doesn't work, because the hash id of the objects are different.

    One possible solution is:

    Based on the selected item id, recover the object on the itemsource collection and set the selected item property to with it.

    Example:

    <ctrls:ComboBoxControlBase SelectedItem="{Binding Path=SelectedProfile, Mode=TwoWay}" ItemsSource="{Binding Path=Profiles, Mode=OneWay}" IsEditable="False" DisplayMemberPath="Name" />
    

    The Property binded to ItemSource is:

    public ObservableCollection<Profile> Profiles
    {
       get { return this.profiles; }
       private set { profiles = value; RaisePropertyChanged("Profiles"); }
    }
    

    The property binded to SelectedItem is:

    public Profile SelectedProfile 
    {
        get { return selectedProfile; }
        set
        {
            if (this.SelectedUser != null)
            {
                this.SelectedUser.Profile = value; 
                RaisePropertyChanged("SelectedProfile");  
            } 
        } 
    }
    

    The recovery code is:

        [Command("SelectionChanged")]
        public void SelectionChanged(User selectedUser)
        {
            if (selectedUser != null)
            {
                if (selectedUser is User)
                {
                    if (selectedUser.Profile != null)
                    {
                        this.SelectedUser = selectedUser;
                        this.selectedProfile = this.Profiles.Where(p => p.Id == this.SelectedUser.Profile.Id).FirstOrDefault();
                        MessageBroker.Instance.NotifyColleagues("ShowItemDetails"); 
                    }
                }
            }            
        }
    

    I hope it helps you. I spent a lot of my time searching for answers, but I couldn´t find.

    0 讨论(0)
  • 2020-12-05 07:02

    I was fighting with this issue for a while. In my case I was using in complex type (List) as the Item Source and was using a KeyType as the selected value. On the load event, the KeyType was getting set to null. This caused everything to break. None of the sub elements would get updated when the key changed. It turned out that when I added a check to make sure the proposed value for KeyType was not null, everything worked as expected.

        #region Property: SelectedKey
        // s.Append(string.Format("SelectedKey : {0} " + Environment.NewLine, SelectedKey.ToString()));
    
        private KeyType _SelectedKey = new KeyType();
        public KeyType SelectedKey
        {
            get { return _SelectedKey; }
            set
            {
                if(value != null )
                    if (!_SelectedKey.Equals(value))
                    {
                        _SelectedKey = value;
                        OnPropertyChanged("SelectedKey");
                    }
            }
        }
        #endregion SelectedKey
    
    0 讨论(0)
  • 2020-12-05 07:05

    I solved the problem by adding dispatcher in UserControl_Loaded event

     Dispatcher.BeginInvoke(DispatcherPriority.Loaded, new Action(() =>
     {
         combobox.SelectedIndex = 0;
     }));
    
    0 讨论(0)
提交回复
热议问题