C# 即使焦点在另一个控件上,如何更改listview选定的行背景色?
我有一个使用条形码扫描仪作为输入设备的程序,这意味着我需要将焦点放在文本框上 该程序有一个listview控件,当扫描某个条形码时,我通过编程选择其中一个项目。我通过以下方式设置行的背景色:C# 即使焦点在另一个控件上,如何更改listview选定的行背景色?,c#,winforms,listview,focus,backcolor,C#,Winforms,Listview,Focus,Backcolor,我有一个使用条形码扫描仪作为输入设备的程序,这意味着我需要将焦点放在文本框上 该程序有一个listview控件,当扫描某个条形码时,我通过编程选择其中一个项目。我通过以下方式设置行的背景色: listviewitem.BackColor = Color.LightSteelBlue; 我尝试过的事情: listview.HideSelection设置为false 设置颜色后调用listview.Focus() listviewitem.Focused设置为true 调用listview.In
listviewitem.BackColor = Color.LightSteelBlue;
我尝试过的事情:
设置为falselistview.HideSelection
- 设置颜色后调用
listview.Focus()
设置为truelistviewitem.Focused
- 调用
listview.Invalidate
- 调用
listview.Update()
- 调用
listview.Refresh()
- 上述各项的不同组合
- 这里的关键是控制焦点。当我选择一个项目时,listview控件没有焦点
- 我通过执行以下操作选择一项:
listView1.Items[index].Selected = true;
- 焦点始终在文本框中
- 计算机没有键盘或鼠标,只有条形码阅读器
private void txtBarcode_Leave(object sender, EventArgs e)
{
this.txtBarcode.Focus();
}
你需要一个文本框来添加代码来模拟我的问题。在这种情况下,你不能将焦点设置在listview控件上
txtBarcode\u Leave
方法将阻止此操作。但如果您希望能够通过单击listview项目来选择它们,只需将下面的代码添加到listview的鼠标单击
事件处理程序即可:
private void listView1_MouseClick(object sender, MouseEventArgs e)
{
ListView list = sender as ListView;
for (int i = 0; i < list.Items.Count; i++)
{
if (list.Items[i].Bounds.Contains(e.Location) == true)
{
list.Items[i].BackColor = Color.Blue; // highlighted item
}
else
{
list.Items[i].BackColor = SystemColors.Window; // normal item
}
}
}
private void listView1\u鼠标单击(对象发送者,鼠标事件目标)
{
ListView list=发送方作为ListView;
对于(int i=0;i
标准的列表视图不允许您设置所选行的背景色。选定行的背景(和前景)颜色始终由操作系统的主题控制
您必须绘制您的ListView
才能绕过此问题,或者您可以使用。ObjectListView是一个围绕.NET WinForms ListView的开源包装器,它使它的使用更加方便,并且可以轻松地允许在普通ListView中非常困难的事情,例如更改选定行的颜色
this.objectListView1.UseCustomSelectionColors = true;
this.objectListView1.HighlightBackgroundColor = Color.Lime;
this.objectListView1.UnfocusedHighlightBackgroundColor = Color.Lime;
当ObjectListView不具有焦点时,将显示该视图
假设您已将ListView
控件的HideSelection
属性设置为False,则您所描述的功能与预期完全相同。这是一个用于演示的屏幕截图。我创建了一个空白项目,在表单中添加了一个ListView
控件和一个TextBox
控件,在ListView
中添加了一些示例项,将其视图设置为“Details”(尽管这在任何视图中都有效),并将HideSelection
设置为false。我处理了TextBox.Leave
事件,正如您在问题中所示,并添加了一些简单的逻辑来选择相应的ListViewItem
,只要它的名称输入到TextBox
注意,在列表视图中选择了“测试项目6”:
现在,正如我最初怀疑的那样,如果你自己胡乱设置BackColor
属性,你会把事情搞砸的。我不知道你为什么要这样做,因为控件已经默认使用默认选择颜色来指示所选项目。如果你想使用不同的颜色,你应该改变你的Windows主题,而不是试图写代码来做到这一点
事实上,如果我在现有代码之外添加行item.BackColor=Color.LightSteelBlue
,以选择与键入到文本框中的名称相对应的ListViewItem
,我得到的结果与上面显示的完全相同。在将焦点设置为控件之前,项目的背景色不会更改。这是预期的行为,因为选定项在有焦点时与其父控件未聚焦时看起来不同。聚焦控件上的选定项使用系统高亮显示颜色绘制;未聚焦控件上的选定项将使用系统3D颜色绘制。否则,就无法判断ListView
控件是否具有焦点。此外,当ListView
控件具有焦点时,操作系统将完全忽略任何自定义的BackColor
属性。背景以默认的系统高光颜色绘制
当然,显式地将焦点设置为ListView
控件会导致自定义背景色应用于ListViewItem
,并且渲染时的颜色与我在计算机上选择的配色方案形成鲜明对比(请记住,并非所有人都使用默认设置)。不过,问题马上变得显而易见:您无法将焦点设置到列表视图
控件,因为您在文本框中编写了代码。请离开事件处理程序方法强>
我现在可以告诉你,在焦点改变事件中设置焦点是错误的。在Windows中,这是一条严格的规则,不允许你做这样的事情,甚至还明确警告你不要这样做。你的回答大概是“我必须”,但这不是借口。如果一切都按预期进行,那么你一开始就不会问这个问题
那么,什么不
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();
}
}
private void lBxDostepneOpcje_SelectedIndexChanged(object sender, EventArgs e)
{
ListViewItem item = lBxDostepneOpcje.FocusedItem as ListViewItem;
ListView.SelectedIndexCollection lista = lBxDostepneOpcje.SelectedIndices;
foreach (Int32 i in lista)
{
lBxDostepneOpcje.Items[i].BackColor = Color.White;
}
if (item != null)
{
item.Selected = false;
if (item.Index == 0)
{
}
else
{
lBxDostepneOpcje.Items[item.Index-1].BackColor = Color.White;
}
if (lBxDostepneOpcje.Items[item.Index].Focused == true)
{
lBxDostepneOpcje.Items[item.Index].BackColor = Color.LightGreen;
if (item.Index < lBxDostepneOpcje.Items.Count-1)
{
lBxDostepneOpcje.Items[item.Index + 1].BackColor = Color.White;
}
}
else if (lBxDostepneOpcje.Items[item.Index].Focused == false)
{
lBxDostepneOpcje.Items[item.Index].BackColor = Color.Blue;
}
}
}
private void listView1_Leave(object sender, EventArgs e)
{
// Set the global int variable (gListView1LostFocusItem) to
// the index of the selected item that just lost focus
gListView1LostFocusItem = listView1.FocusedItem.Index;
}
private void listView1_DrawItem(object sender, DrawListViewItemEventArgs e)
{
// If this item is the selected item
if (e.Item.Selected)
{
// If the selected item just lost the focus
if (gListView1LostFocusItem == e.Item.Index)
{
// Set the colors to whatever you want (I would suggest
// something less intense than the colors used for the
// selected item when it has focus)
e.Item.ForeColor = Color.Black;
e.Item.BackColor = Color.LightBlue;
// Indicate that this action does not need to be performed
// again (until the next time the selected item loses focus)
gListView1LostFocusItem = -1;
}
else if (listView1.Focused) // If the selected item has focus
{
// Set the colors to the normal colors for a selected item
e.Item.ForeColor = SystemColors.HighlightText;
e.Item.BackColor = SystemColors.Highlight;
}
}
else
{
// Set the normal colors for items that are not selected
e.Item.ForeColor = listView1.ForeColor;
e.Item.BackColor = listView1.BackColor;
}
e.DrawBackground();
e.DrawText();
}
public class ListViewEx : ListView
{
public ListViewEx() : base()
{
this.DoubleBuffered = true;
}
}