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