Во-первых, справедливое предупреждение: Я - полный новичок с C# и WPF.
У меня есть поле комбинированного списка (доступный для редактирования, доступный для поиска), и я хотел бы смочь прервать клавишу Delete и удалить в настоящее время выделяемый объект из списка. Поведение, которое я ищу, похоже на поведение MS Outlook при вводе в адреса электронной почты. При предоставлении нескольких символов выпадающий список потенциальных соответствий отображен. Если Вы перемещаетесь в один из них (с клавишами со стрелками) и совершаете нападки, Удаляют, та запись постоянно удалена. Я хочу сделать это с записью в поле комбинированного списка.
Вот (упрощенный) XAML:
Обработчик:
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'...
Так: как я получаю доступ к тому значению? Следует иметь в виду, что объект не был выбран. Это просто выделяется, поскольку мышь нависает над ним.
Спасибо за помощь.
Вот снимок экрана, показывающий дисплей отладчика. Я навис над "полем" и когда короткая сводка была отображена, я затем навис над + символ для расширения до этого изображения:
сопроводительный текст http://www.freeimagehosting.net/uploads/2cff35d340.gif
Свойство выделенного элемента является закрытым членом, поэтому его нельзя вызвать из другого класса.
альтернативный текст http://www.freeimagehosting.net/uploads/1e4dc53cee.png
Я считаю, что вам нужно использовать Reflection, чтобы получить доступ к непубличным участникам. Вот сообщение SO на эту тему: Доступ к непубличным членам - ReflectionAttribute
Ниже приведен окончательный код, вдохновленный ответом Жана Аззопарди. 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
}
}
}
Вы можете создать свой собственный обработчик событий 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);
}
}
}
Определение System.Windows.Controls.ComboBox не содержит свойства HighlightedItem
- вот почему вы код не компилируется.
Используете ли вы поле со списком, производное от System.Windows.Controls.ComboBox? Затем просто приведите его к соответствующему типу.
Позднее примечание: Если вы хотите поймать выделенное событие ComboBox, прочтите эту ссылку - она решает именно эту проблему.