2010-04-27 2 views
5

Во-первых, справедливое предупреждение: я полный новичок с C# и WPF.В поле со списком, как определить выделенный элемент (не выбранный элемент)?

У меня есть combobox (редактируемый, доступный для поиска), и я хотел бы иметь возможность перехватить клавишу 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'...

Итак: как мне получить доступ к этому значению? Имейте в виду, что пункт не выбран. Он просто подсвечивается, когда мышь нависает над ним.

Благодарим за помощь.

Вот скриншот, показывающий дисплей отладчика. Я парил над «поле» и когда отображается сводная одна линия, я тогда носился над + полукокса расширить на это изображение:

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

+0

Что именно вы имеете в виду, когда вы говорите, что вы можете увидеть box.HighlightedItem в отладчике? Это в окне часов? В ComboBox нет открытого свойства HighlightedItem. –

+0

Я добавил картинку в нижней части сообщения. –

ответ

2

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

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

Я считаю, что вам нужно использовать Reflection, чтобы получить в непубличных членов. Вот сообщение СО по этой теме: Access non-public members - ReflectionAttribute

+0

Это похоже на это. Благодаря! Я поставлю окончательный код в отдельном ответе, но принесу вам «победителя». –

+0

Джин, как вы получаете окно «Часы», чтобы выделить «Непубличные члены»? Я пробовал это в VS2008 и VS2010 (Pro edition), и это не так. Если бы это было, я мог бы решить проблему намного раньше. –

+0

Наведите указатель мыши на элемент, который я хочу увидеть, затем перейдите к Raw View, затем база, затем не публичные участники обычно отображаются. Иногда вы используете несколько уровней (base), если используете наследование. Я использую VS 2010 Ultimate (все еще использую бесплатный RC, пока он длится;)), но я думаю, что это должно быть в Pro. –

-1

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

Вы используете комбинированное поле, полученное из System.Windows.Controls.ComboBox? Затем просто нанесите его на соответствующий тип.

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

+0

Что бы это за тип? И почему отладчик показывает HighlightedItem? –

+0

Не знаете, что вы ищете в отладчике - можете ли вы скопировать/вставить какую переменную вы смотрите и какой тип вы получаете для этой переменной? – Ando

+0

Изображение добавлено в исходное сообщение. Это то, что я ищу. –

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); 
     } 
    } 
} 
+0

На самом деле я не использую Формы, а WPF 3.5 –

7

Ниже приводится окончательный код, в соответствии с ответом Жана Аззопарди.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

У меня была такая же проблема, и ваше решение решило ее, но она не работала из коробки. Мне пришлось посмотреть некоторую информацию в отладчике, чтобы найти, что свойство HighlightedItem было названо «HighlightedElement» в моей версии (.NET 4.0), поэтому я изменил эту строку в вызове GetProperty(). Остальное работает безупречно. Благодаря! –

+1

Мне тоже пришлось использовать свойство «HighlightedElement», но у меня была другая проблема в том, что мне нужен элемент данных. Мне удалось сохранить значение, возвращенное из 'GetValue()' как 'ComboBoxItem', а затем использовать свойство Content в нем, чтобы получить фактический элемент, к которому привязан элемент« HighlightedElement ». – Kidiskidvogingogin

Смежные вопросы