tralladas Ответов: 1

В WPF ComboBox, для текст изменен не меняется selectedvalue


Привет,

Я использую элемент управления ComboBox в WPF UserControl. Я связал его с сущностью. Проблема в том, что если я набираю текст вручную (IsEditable = " True") текст иногда не совпадает со значением DisplayMemberPath выбранного значения.

Это мой код Xaml:
ItemsSource="{Binding Companies, Mode=OneWay}"
                                      DisplayMemberPath="Name"
                                      SelectedValue = "{Binding SelectedItem.CompanyId, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"
                                      SelectedValuePath="CompanyId"
                                      IsSynchronizedWithCurrentItem="True"
                                      IsEditable="True"

А это c# компании (ItemSource):
public class CompanyEntity : BaseEntity
    {
                
        public int? CompanyId { get; set; }
        public string Name
        {
            get
            {
                return GetValue(() => Name);
            }
            set
            {
                SetValue(() => Name,value);
            }
        }
}

(где GetValue и SetValue воспроизводят OnNotifiPropertyChanged.)

Итак, если у меня есть эта компания:
CompanyId:1 Название: Microsoft
CompnayId:2 Название: Apple

Если я наберу вручную "Mi", то в выпадающем списке автоматически выберу " Microsoft (SelectedValue = 1, Text = Microsoft). Но если я удалю последнее слово, SelectedValue останется 1, а текст изменится на"Mi". Поэтому я выбрал значение, которое не соответствует компании с Id=1.

¿Кто-нибудь экспериментировал с этой проблемой и знает, как ее решить?

Что я уже пробовал:

Я попытался изменить SelectedValue вручную таким образом:

XAML-Код Выпадающего Списка :
TextBoxBase.TextChanged="ComboBox_TextChanged"


В C# код позади :
private void ComboBox_TextChanged(object sender, TextChangedEventArgs e)
       {
           if (sender is ComboBox)
           {
               ComboBox combo = sender as ComboBox;

               if (!String.IsNullOrWhiteSpace(combo.Text))
               {
                   if (combo.SelectedValue == null || (int)combo.SelectedValue == 0)
                       return;
                   else
                   {
                       var propertyInfo =                    combo.SelectedItem.GetType().GetProperty(combo.DisplayMemberPath);
                       string value = propertyInfo.GetValue(combo.SelectedItem, null).ToString();
                       if (!value.Equals(combo.Text, StringComparison.OrdinalIgnoreCase))
                       {
                           combo.SelectedValue = 0;
                       }
                   }
               }


           }
       }


Но в этом случае, когда я обновляю SelectedValue, он автоматически удаляет текст.

Другой вариант, который я пробовал, - это обновление текста после SelectedValue = 0, но затем курсор перемещается в начало, что приводит к плохому пользовательскому опыту.

1 Ответов

Рейтинг:
1

Rav! Srivastava

Делай вот так. После изменения значения в combobox проверьте значение для " компании.CurrentItem " в viewmodel. Если у вас есть какие-либо сомнения, пожалуйста, дайте мне знать.
код XAML-

<ComboBox x:Name="comboBox" HorizontalAlignment="Left" Margin="56,79,0,0"

         ItemsSource="{Binding Companies, Mode=OneWay}"

                                      DisplayMemberPath="Name"

                                      SelectedValue = "{Binding SelectedItem.CompanyId, ValidatesOnDataErrors=True, ValidatesOnExceptions=True}"

                                      SelectedValuePath="CompanyId"

                                      IsSynchronizedWithCurrentItem="True"

                                      IsEditable="True" VerticalAlignment="Top" Width="222"/> 


Код ViewModel-

public class CompanyEntity
    {

        public int? CompanyId { get; set; }
        public string Name { get; set; }
    }
   
    class MainWindowVM
    {
        ObservableCollection<CompanyEntity> companies = new ObservableCollection<CompanyEntity>();
        ICommand saveCommand = null;
        public MainWindowVM()
        {
            companies.Add(new CompanyEntity { CompanyId = 1,Name= "Microsoft" });
            companies.Add(new CompanyEntity { CompanyId = 2,Name= "Apple" });
        }
        public ICommand SaveCommand
        {
            get
            {
                return saveCommand = new RelayCommand(Save);
            }
        }

        private void Save()
        {
            
        }

        public CollectionView Companies
        {
            get
            { 
                return CollectionViewSource.GetDefaultView(companies) as CollectionView;
            }
        }
    }