简体   繁体   English

在组合框中,如何确定突出显示的项目(未选择项目)?

[英]In a combobox, how do I determine the highlighted item (not selected item)?

First, fair warning: I am a complete newbie with C# and WPF. 首先,公平警告:我是C#和WPF的全新手。

I have a combobox (editable, searchable) and I would like to be able to intercept the Delete key and remove the currently highlighted item from the list. 我有一个组合框(可编辑,可搜索),我希望能够拦截删除键并从列表中删除当前突出显示的项目。 The behavior I'm looking for is like that of MS Outlook when entering in email addresses. 在输入电子邮件地址时,我正在寻找的行为类似于MS Outlook。 When you give a few characters, a dropdown list of potential matches is displayed. 当您提供几个字符时,会显示潜在匹配的下拉列表。 If you move to one of these (with the arrow keys) and hit Delete, that entry is permanently removed. 如果您移动到其中一个(使用箭头键)并单击“删除”,则会永久删除该条目。 I want to do that with an entry in the combobox. 我想通过组合框中的条目来做到这一点。

Here is the XAML (simplified): 这是XAML(简化):


<ComboBox x:Name="Directory"
    KeyUp="Directory_KeyUp"
    IsTextSearchEnabled="True"
    IsEditable="True"
    Text="{Binding Path=CurrentDirectory, Mode=TwoWay}"
    ItemsSource="{Binding Source={x:Static self:Properties.Settings.Default}, 
        Path=DirectoryList, Mode=TwoWay}" />

The handler is: 处理程序是:


private void Directory_KeyUp(object sender, KeyEventArgs e)
{
    ComboBox box = sender as ComboBox;
    if (box.IsDropDownOpen &&  (e.Key == Key.Delete))
    {
        TrimCombobox("DirectoryList", box.HighlightedItem);  // won't compile!
    }
}

When using the debugger, I can see box.HighlightedItem has the value I want but when I try and put in that code, it fails to compile with: 使用调试器时,我可以看到box.HighlightedItem具有我想要的值,但是当我尝试输入该代码时,它无法编译:

System.Windows.Controls.ComboBox' does not contain a definition for 'HighlightedItem'...

So: how do I access that value? 那么:我如何访问该值? Keep in mind that the item has not been selected. 请记住,该项目尚未被选中。 It is merely highlighted as the mouse hovers over it. 它只是在鼠标悬停在它上面时突出显示。

Thanks for your help. 谢谢你的帮助。

Here is a screenshot showing the debugger's display. 这是显示调试器显示的屏幕截图。 I hovered over "box" and when the one-line summary was displayed, I then hovered over the + char to expand to this image: 我徘徊在“盒子”上,当显示单行摘要时,我然后盘旋在+ char上以展开到这个图像:

alt text http://www.freeimagehosting.net/uploads/2cff35d340.gif alt text http://www.freeimagehosting.net/uploads/2cff35d340.gif

Below is the final code, as inspired by Jean Azzopardi's answer. 以下是Jean Azzopardi答案启发的最终代码。 The HighlightedItem that was showing up in the debugger was a non-public property and I am forcing access with a sequence of GetType().GetProperty().GetValue() 在调试器中显示的HighlightedItem是非公共属性,我使用GetType().GetProperty().GetValue()序列强制访问GetType().GetProperty().GetValue()

private void Directory_KeyUp(object sender, KeyEventArgs e)
{
    ComboBox box = sender as ComboBox;
    if (box.IsDropDownOpen && (e.Key == Key.Delete))
    {
        const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
        PropertyInfo hl = box.GetType().GetProperty("HighlightedItem", flags);
        if (hl != null)
        {
            String hlString = hl.GetValue(sender, null) as String;
            // TODO: remove from DirectoryList
        }
    }
}

The Highlighted Item property is a Non-Public member, so you can't call it from another class. 突出显示的项目属性是非公共成员,因此您无法从其他类调用它。

alt text http://www.freeimagehosting.net/uploads/1e4dc53cee.png alt text http://www.freeimagehosting.net/uploads/1e4dc53cee.png

I believe you need to use Reflection to get at Non-Public members. 我相信你需要使用Reflection来吸引非公众成员。 Here's a SO post on the subject: Access non-public members - ReflectionAttribute 这是关于这个主题的SO帖子: 访问非公开成员 - ReflectionAttribute

You can create your own DrawItem Event handler and save the index of the items as they are actively being drawn and keep the DrawItemState.Selected (ie. the highlighted) one. 您可以创建自己的DrawItem事件处理程序,并在项目被主动绘制时保存项目的索引,并保留DrawItemState.Selected(即突出显示的)项目。

void Main()
{
    Application.Run(new Form1());
}

public partial class Form1 : Form
{
    ComboBox ComboBox1;
    string[] ds = new string[]{"Foo", "Bar", "Baz"};

    public Form1 ()
    {
        InitializeComboBox();
    }

    private void InitializeComboBox()
    {
        ComboBox1 = new ComboBox();

        ComboBox1.DataSource = ds;
        Controls.Add(ComboBox1);

        ComboBox1.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawVariable;
        ComboBox1.DrawItem += new DrawItemEventHandler(ComboBox1_DrawItem);
    }

    private void ComboBox1_DrawItem(object sender, DrawItemEventArgs e)
    {
        e.DrawBackground();
        e.Graphics.DrawString(ds[e.Index],ComboBox1.Font,Brushes.Black,e.Bounds);

        if (e.State == DrawItemState.Selected)
        {
            //stores the "HighlightedIndex" in the control's tag field.  Change as you see fit.
            ComboBox1.Tag = e.Index; 
            //Console.WriteLine(e.Index);
        }
    }
}

The definition of System.Windows.Controls.ComboBox does not contain a property HighlightedItem - that's why you're code does not compile. System.Windows.Controls.ComboBox的定义不包含属性HighlightedItem - 这就是你的代码无法编译的原因。

Are you using a combo box derived from System.Windows.Controls.ComboBox? 您使用的是从System.Windows.Controls.ComboBox派生的组合框吗? Then just cast it to the appropriate type. 然后将其强制转换为适当的类型。

Later note: If you want to catch the highlighted event of a ComboBox read this link - it addresses exactly this issue. 稍后注意:如果你想捕捉ComboBox突出显示的事件,请阅读链接 - 它正好解决了这个问题。

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

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