WPF: отключить выбранный элемент в ComboBox - PullRequest
0 голосов
/ 02 июля 2018

Я просматривал сообщения в течение 3 часов без разрешения. Я новичок в WPF и создал ComboBox ниже:

enter image description here

К сожалению, я не могу отключить выделение выбранного элемента. У кого-нибудь есть жизнеспособное решение?

Код :

            <StackPanel Grid.Column="1" 
                        Margin="800,0,0,0"
                        Width="135"
                        HorizontalAlignment="Right"
                        VerticalAlignment="Center">
                <ComboBox Name="LangComboBox"
                          IsEditable="True"
                          IsReadOnly="True"
                          Text="Select Language">
                    <ComboBoxItem>English</ComboBoxItem>
                    <ComboBoxItem>Spanish</ComboBoxItem>
                    <ComboBoxItem>Both</ComboBoxItem>
                </ComboBox>
            </StackPanel>

1 Ответ

0 голосов
/ 04 июля 2018

Прежде всего я хотел бы уточнить, что мой хочет быть конструктивным ответом и хочет попытаться распространить культуру хорошего программирования. Мы все всегда должны учиться программированию, я тоже! Если вы не знаете какой-либо темы, рекомендуется изучать, возможно, начиная с хорошей книги или с официальной документации платформы.

При этом давайте перейдем к некоторым возможным подходам к вашей проблеме.

Прежде всего, тот факт, что выбор в комбинированном ящике осуществляется именно таким образом, обусловлен базовым шаблоном комбинированного списка , который я предлагаю вам просмотреть: https://msdn.microsoft.com/library/ms752094(v=vs.85).aspx)

То, что вы ищете, - это другое поведение комбинированного списка:

  1. Разрешить отображение значения по умолчанию
  2. После выбора элемента текст внутри него не подчеркивается

Первый подход может быть основан на шаблоне ComboBox : комбинированный список построен таким образом, что, если он редактируемый, его шаблон содержит текстовое поле с именем PART_EditableTextBox воздействуя на текстовое поле, например, отключив его, вы можете получить желаемый результат.

И это может быть реализовано различными способами:

  1. Вставка обработчика событий с выделенным кодом, который отключает текстовое поле при загрузке комбинированного списка
  2. С подключенным поведением, которое позволяет добавлять пользовательские поведения к элементам управления (https://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF)
  3. Напишите пользовательский элемент управления, который может вставить часть типа водяного знака в ваш список

Теперь рассмотрим первый подход, который быстрее всего реализовать, поэтому код может быть следующим:

<ComboBox Name="LangComboBox" IsEditable="True" IsReadOnly="True" 
                          Loaded="LangComboBox_Loaded"
                          Text="Select language">
    <ComboBoxItem Content="English"/>
    <ComboBoxItem Content="Spanish"/>
    <ComboBoxItem Content="Both"/>
</ComboBox>

В коде позади:

private void LangComboBox_Loaded(object sender, RoutedEventArgs e)
{
    ComboBox ctrl = (ComboBox)sender;
    TextBox Editable_tb = (TextBox)ctrl.Template.FindName("PART_EditableTextBox", ctrl);
    if (Editable_tb != null)
    {
        // Disable the textbox
        Editable_tb.IsEnabled = false;
    }
}

Этот подход, однако, имеет недостатки, среди которых тот факт, что если пользователь хочет отменить выбор / сброс значения комбо, он не может этого сделать.

Таким образом, вы можете следовать по другому пути, используя шаблон MVVM .

Исходя из мира веб-программирования, вы должны знать шаблон MVC , в WPF наиболее распространенным шаблоном является MVVM или Model - View - ViewModel Между этими двумя паттернами есть разные общие черты, и я предлагаю вам взглянуть на них: Mvvm Pattern .

Вы можете создать класс с моделью, которая будет размещена в комбо, например:

public class Language
    {
        public int Id { get; set; }
        public string Description { get; set; }

        public Language(int id, string desc)
        {
            this.Id = id;
            this.Description = desc;
        }
    }

    public class YourDataContext : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private List<Language> _Languages;
        public List<Language> Languages
        {
            get
            {
                return _Languages;
            }
            set
            {
                _Languages = value;
                OnPropertyChanged("Languages");
            }
        }

        private Language _selectedLanguage;
        public Language SelectedLanguage
        {
            get
            {
                return _selectedLanguage;
            }
            set
            {
                _selectedLanguage = value;
                OnPropertyChanged("SelectedLanguage");

            }
        }

        public YourDataContext()
        {
            // Initialization of languages
            Languages = new List<Language>();

            Languages.Add(new Language(0, "None - Select a Language"));

            Languages.Add(new Language(1, "English"));

            Languages.Add(new Language(2, "Spanish"));

            Languages.Add(new Language(3, "Both"));

            SelectedLanguage = Languages.First();
        }

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
        // some other properties and commands
    }


    // Your Window class

    public MainWindow()
    {
        InitializeComponent();
        var dc = new YourDataContext();
        DataContext = dc;


    }


<ComboBox ItemsSource="{Binding Languages}"
                          DisplayMemberPath="Description"
                          SelectedItem="{Binding SelectedLanguage}"/>

Обратите внимание, что теперь поле со списком больше не доступно для редактирования, и теперь можно сбросить выбор.

Вы можете управлять выбором, используя модель:

if(dc.SelectedLanguage.Id == 0)
    {
        //No language selected
    }

Есть много разных способов достичь того, чего вы хотите, я надеюсь, что это дало вам хороший старт.

Хорошее программирование для всех.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...