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

C# 在组合框中,如何确定突出显示的项目(非选定项目)?,c#,wpf-controls,C#,Wpf Controls,首先,公平的警告:我是一个有C#和WPF的完全新手 我有一个组合框(可编辑,可搜索),我希望能够截取删除键并从列表中删除当前突出显示的项目。我正在寻找的行为类似于MS Outlook在输入电子邮件地址时的行为。当您输入几个字符时,将显示潜在匹配项的下拉列表。如果移动到其中一个(使用箭头键)并单击Delete,则该条目将被永久删除。我想用组合框中的一个条目来实现这一点 以下是XAML(简化): 当使用调试器时,我可以看到框。HighlightedItem具有我想要的值,但当我尝试输入该代码时,它无

首先,公平的警告:我是一个有C#和WPF的完全新手

我有一个组合框(可编辑,可搜索),我希望能够截取删除键并从列表中删除当前突出显示的项目。我正在寻找的行为类似于MS Outlook在输入电子邮件地址时的行为。当您输入几个字符时,将显示潜在匹配项的下拉列表。如果移动到其中一个(使用箭头键)并单击Delete,则该条目将被永久删除。我想用组合框中的一个条目来实现这一点

以下是XAML(简化):

当使用调试器时,我可以看到
框。HighlightedItem
具有我想要的值,但当我尝试输入该代码时,它无法编译:

System.Windows.Controls.ComboBox'不包含“HighlightedItem”的定义…

那么:我如何访问该值?请记住,尚未选择该项目。它只是在鼠标悬停在其上时高亮显示

谢谢你的帮助

下面是显示调试器显示的屏幕截图。我将鼠标悬停在“框”上,当显示单行摘要时,我将鼠标悬停在+字符上以展开此图像:

的定义不包含属性
HighlightedItem
-这就是为什么代码不编译

是否使用从System.Windows.Controls.ComboBox派生的组合框?然后将其转换为适当的类型

稍后注意:
如果您想捕获组合框读取链接的突出显示事件,它正好解决了这个问题。

您可以创建自己的DrawItem事件处理程序,并在项目处于活动绘制状态时保存项目的索引,并保持DrawItemState。选中(即突出显示的)一个


突出显示的项属性是非公共成员,因此不能从其他类调用它


我相信你需要用反思来对付非公众成员。这里有一篇关于这个主题的SO帖子:

以下是最终代码,灵感来自Jean Azzopardi的回答。调试器中显示的
HighlightedItem
是一个非公共属性,我正在使用
GetType().GetProperty().GetValue()序列强制访问


那是什么类型的?为什么调试器显示HighlightedItem?不知道您在调试器中看到了什么-您可以复制/粘贴您正在查看的变量以及该变量的类型吗?图片添加到原始帖子中。这就是我要寻找的。解决你的问题的一个办法是抓住重点事件——我编辑了我的帖子,请查看链接以获取更多信息。唉,这似乎是针对Windows.Forms而不是WPF的。谢谢,当你说你可以在调试器中看到box.HighlightedItem时,你到底是什么意思?它在手表的橱窗里吗?ComboBox中没有公共的HighlightedItem属性。我在帖子的底部添加了一张图片。实际上我并没有使用表单,而是使用WPF 3.5,这似乎已经做到了。谢谢我将把最后的代码放在一个单独的答案中,但把“获胜者”归功于你。珍,你如何让观察窗口将“非公共成员”分离出来?我在VS2008和VS2010(专业版)中尝试过这个,但它没有这样做。如果有,我可能会更快地解决问题。我将鼠标悬停在我想要查看的项目上,然后转到原始视图,然后转到基本视图,然后通常会显示非公共成员。如果使用继承,有时会有多个级别的(基础)。我正在使用VS2010Ultimate(在它持续的时候仍然使用免费的RC),但我认为它应该是专业版的。对我来说没有原始视图。必须是终极版,我没有11000美元可花!无论如何,谢谢。仅供参考,我认为你仍然可以免费获得RC,但它将在未来几个月到期。就我个人而言,我想问一个问题,看看原始视图是否只在2010年才可用。成千上万的SO用户使用多个版本的VisualStudio,您应该会得到答案。另外,请检查您的调试设置。我也遇到了同样的问题,您的解决方案解决了它,但它并没有开箱即用。我必须查看调试器中的一些信息才能发现“HighlightedItem”属性在我的版本(.NET 4.0)中被命名为“HighlightedElement”,因此我在GetProperty()调用中更改了该字符串。其余的工作完美无瑕。谢谢我也不得不使用
HighlightedElement
属性,但还有一个问题,我需要数据绑定项。我能够将从
GetValue()
返回的值存储为
ComboBoxItem
,然后使用其中的
Content
属性来获取绑定了
HighlightedElement
的实际项。

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

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