То, что вы описываете, работает в точности, как ожидалось, при условии, что вы установили для свойства HideSelection
элемента управления ListView
значение False. Вот скриншот для демонстрационных целей. Я создал пустой проект, добавил ListView
элемент управления и TextBox
элемент управления в форму, добавил несколько образцов элементов в ListView
, установил для его представления значение «Подробности» (хотя это работает в любом представлении) и установил для HideSelection
значение false. Я обработал событие TextBox.Leave
так же, как вы показали в вопросе, и добавил некоторую простую логику для выбора соответствующего ListViewItem
всякий раз, когда его имя было введено в TextBox
. Обратите внимание, что в ListView
: выбран "Test Item Six"
Теперь, как я изначально подозревал, вы все испортите, если будете обезьянничать с настройкой свойства BackColor
самостоятельно. Я не уверен, зачем вам это нужно, поскольку элемент управления уже использует цвета выбора по умолчанию для обозначения выбранных элементов по умолчанию. Если вы хотите использовать разные цвета, вам следует изменить тему Windows, а не пытаться писать код для этого.
Фактически, если я добавлю строку item.BackColor = Color.LightSteelBlue
в дополнение к моему существующему коду, чтобы выбрать ListViewItem
, соответствующий имени, введенному в TextBox
, я получу в точности то же, что показано выше. Цвет фона элемента не изменится, пока вы не установите фокус на элемент управления. Это ожидаемое поведение, поскольку выбранные элементы в фокусе выглядят иначе, чем когда их родительский элемент управления не сфокусирован. Выбранные элементы на сфокусированных элементах управления окрашиваются в системный цвет выделения; выбранные элементы на несфокусированных элементах управления окрашиваются в системный 3D-цвет. В противном случае было бы невозможно определить, находится ли элемент управления ListView
в фокусе. Более того, любое настраиваемое свойство BackColor
полностью игнорируется операционной системой, когда элемент управления ListView
находится в фокусе. Фон окрашивается в системный цвет выделения по умолчанию.
Явная установка фокуса на элемент управления ListView
, конечно, приводит к тому, что пользовательский цвет фона применяется к ListViewItem
, и вещи отображаются с цветом, который очень сильно контрастирует с цветовой схемой, которую я выбрал на своем компьютере (помните, что не все используют значения по умолчанию). Однако проблема становится очевидной сразу: нельзя установить фокус на ListView
элемент управления из-за кода, который вы написали в методе обработчика событий TextBox.Leave
!
Я могу сказать вам прямо сейчас, что установка фокуса в событии смены фокуса - неправильный поступок. Это жесткое правило в Windows: вам не разрешается делать подобные вещи, и документация даже предупреждает вас явно не делать этого. Предположительно, ваш ответ будет примерно таким: «Я должен», но это не оправдание. Если бы все работало должным образом, вы бы вообще не задавали этот вопрос.
И что теперь? Дизайн вашего приложения нарушен. Я предлагаю исправить это. Не пытайтесь самостоятельно установить свойство BackColor
, чтобы указать, что элемент выбран. Это конфликтует со способом по умолчанию, которым Windows выделяет выбранные элементы. Кроме того, не пытайтесь установить фокус в событии, изменяющем фокус. Windows явно запрещает это, и в документации ясно сказано, что вы не должны этого делать. Если на целевом компьютере нет мыши или клавиатуры, непонятно, как пользователь собирается установить фокус на что-либо еще, если только вы не напишете код для этого, чего делать не следует.
Но я на удивление мало верю, что вы захотите исправить свое приложение. Люди, игнорирующие предупреждения в документации, как правило, те же люди, которые не прислушиваются к добрым советам на сайтах вопросов и ответов. Так что я брошу вам кость и расскажу, как в любом случае добиться желаемого эффекта. Суть заключается в том, чтобы не устанавливать свойство ListViewItem
Selected
, что позволяет избежать конфликта между вашим пользовательским BackColor
и системным цветом выделения по умолчанию. Это также освобождает вас от необходимости явно устанавливать фокус на элемент управления ListView
и обратно снова (что, как мы установили выше, на самом деле не происходит, учитывая ваш метод обработчика событий Leave
). Это приведет к следующему результату:
А вот код - он не очень красивый, но это просто доказательство концепции, а не образец передового опыта:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
listView1.View = View.Details;
listView1.HideSelection = false;
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
foreach (ListViewItem item in listView1.Items)
{
if (item.Text == textBox1.Text)
{
item.BackColor = Color.LightSteelBlue;
return;
}
}
}
private void textBox1_Leave(object sender, EventArgs e)
{
this.textBox1.Focus();
}
}
04.03.2011