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

时间:2010-04-27 18:39:31

标签: c# wpf-controls

首先,公平警告:我是C#和WPF的新手。

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

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

处理程序是:


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

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

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

那么:我如何访问该值?请注意,该项目已选择。它只是在鼠标悬停在它上面时突出显示。

感谢您的帮助。

以下是显示调试器显示的屏幕截图。我徘徊在“盒子”上,当显示单行摘要时,我然后在+ char上方盘旋以扩展到此图像:

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

4 个答案:

答案 0 :(得分:7)

以下是Jean Azzopardi答案启发的最终代码。调试器中显示的HighlightedItem是非公共属性,我强制使用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
        }
    }
}

答案 1 :(得分:2)

突出显示的项目属性是非公共成员,因此您无法从其他类别调用它。

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

我相信您需要使用Reflection来获取非公开成员。这是关于这个主题的SO帖子:Access non-public members - ReflectionAttribute

答案 2 :(得分:0)

您可以创建自己的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);
        }
    }
}

答案 3 :(得分:-1)

System.Windows.Controls.ComboBox的定义不包含属性HighlightedItem - 这就是您编译代码的原因。

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

稍后注意: 如果您想捕获ComboBox的突出显示事件,请阅读this链接 - 它正好解决了这个问题。