简体   繁体   English

WPF:禁用组合框中的所选项目

[英]WPF: Disable the selected item in ComboBox

I have been going through posts for 3 hours now with no resolution. 我已经经历了3个小时的帖子,没有任何解决方法。 I am new to WPF and created the ComboBox below: 我是WPF的新手,并在下面创建了ComboBox:

在此处输入图片说明

Unfortunately I cannot disable the highlighting of the selected item. 不幸的是,我无法禁用所选项目的突出显示。 Does anyone have a viable solution? 有没有人有可行的解决方案?

Code : 代码

            <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>

I would like to clarify first of all that mine wants to be constructive answer and want to try to spread the culture of good programming. 首先,我想澄清一下,我想成为建设性的 答案,并想传播良好的编程文化。 We all have always to learn about programming, me too! 我们所有人也总是要学习编程! If you do not know a topic, it is good practice to study perhaps starting from a good book or from the official documentation of the platform. 如果您不知道某个主题,那么最好从一本好书或该平台的官方文档开始学习。

That said let's move on to some possible approaches to your problem. 也就是说,让我们继续一些解决问题的可能方法。

First of all, the fact that the selection in the combobox is that way is due to the basic template of the combobox that I invite you to view: https://msdn.microsoft.com/library/ms752094(v=vs.85).aspx ) 首先,组合框中的选择是这样的事实是由于我邀请您查看的组合框基本模板https : //msdn.microsoft.com/library/ms752094(v=vs.85 ).aspx

What you are looking for is a different behavior of the combobox: 您正在寻找的是组合框的其他行为:

  1. Allow display of a default value 允许显示默认值
  2. Once an element is selected, the text inside it is not underlined 选定元素后,其内部的文本将不加下划线

A first approach could be based on the ComboBox template : the combobox is constructed in such a way that, if it is editable, its template contains a textbox called PART_EditableTextBox by acting on the textbox, for example by making it disabled, you can get the result you want. 第一种方法可以基于ComboBox模板 :组合框的构造方式是,如果可编辑,则其模板可以通过作用于文本框来包含一个名为PART_EditableTextBox的文本框,例如,通过禁用它,您可以你想要的结果。

And this can be implemented in different ways: 这可以通过不同的方式实现:

  1. Inserting a code-behind event handler that disables the textbox when the combobox is loaded 插入代码隐藏事件处理程序,该事件处理程序在加载组合框时禁用文本框
  2. With an Attached behavior that allows you to add custom behaviors to the controls ( https://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF ) 通过附加行为,您可以将自定义行为添加到控件( https://www.codeproject.com/Articles/28959/Introduction-to-Attached-Behaviors-in-WPF
  3. Write a custom control that maybe insert a watermark type part to your combobox 编写一个可能将水印类型的部分插入到组合框的自定义控件

Now consider the first approach that is the fastest to implement so the code could be the following: 现在考虑最快实现的第一种方法,因此代码如下:

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

In the code-behind: 在后面的代码中:

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;
    }
}

This approach, however, has drawbacks, among which the fact that if the user wants to deselect / reset the value of the combo can not do it. 但是,这种方法具有缺点,其中,如果用户要取消选择/重置组合的值,则无法做到这一点。

So you could follow another path using the MVVM pattern. 因此,您可以使用MVVM模式遵循另一条路径。

Coming from the world of web programming you should know the MVC pattern, in WPF the most common pattern is MVVM or Model - View - ViewModel between the two patterns there are different things in common and I invite you to take a look at them: Mvvm Pattern . 来自Web编程世界,您应该了解MVC模式,在WPF中,最常见的模式是MVVM或Model-View-ViewModel ,这两种模式之间有共同点,我邀请您一起看看它们: Mvvm模式

You could create a class with the model that will be hosted in the combo for example: 您可以使用将在组合中托管的模型创建一个类,例如:

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}"/>

Note that now the combobox is no longer editable and it is possible to reset the selection. 请注意,现在该组合框不再可编辑,并且可以重置选择。

You can manage the selection using the model: 您可以使用模型来管理选择:

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

There are a lot of different ways to achieve what you want, i hope this gave you some good point to start from. 有很多方法可以实现您想要的,我希望这可以给您一些好的起点。

Good programming to everyone. 好的编程给大家。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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