Как определить выделенный элемент в выпадающем списке (не выбранный элемент)? - PullRequest
5 голосов
/ 27 апреля 2010

Во-первых, честное предупреждение: я новичок в 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, чтобы развернуть это изображение:

альтернативный текст http://www.freeimagehosting.net/uploads/2cff35d340.gif

Ответы [ 4 ]

7 голосов
/ 29 апреля 2010

Ниже приведен окончательный код, вдохновленный ответом Жана Аццопарди.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
        }
    }
}
2 голосов
/ 28 апреля 2010

Свойство Highlighted Item является непубличным членом, поэтому его нельзя вызвать из другого класса.

альтернативный текст http://www.freeimagehosting.net/uploads/1e4dc53cee.png

Полагаю, вам нужно использовать Reflection, чтобы попасть на непубличных участников. Вот SO сообщение на эту тему: Доступ к закрытым членам - ReflectionAttribute

0 голосов
/ 28 апреля 2010

Вы можете создать свой собственный обработчик события 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);
        }
    }
}
0 голосов
/ 27 апреля 2010

Определение System.Windows.Controls.ComboBox не содержит свойства HighlightedItem - поэтому ваш код не компилируется.

Используете ли вы поле со спискомпроисходит от System.Windows.Controls.ComboBox?Затем просто приведите его к соответствующему типу.

Позже примечание: Если вы хотите перехватить выделенное событие ComboBox, прочитайте эту ссылку - она ​​решает именно эту проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...