即使关注另一个控件,如何更改列表视图选定行的背景色? [英] How to change listview selected row backcolor even when focus on another control?

查看:8
本文介绍了即使关注另一个控件,如何更改列表视图选定行的背景色?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用条形码扫描仪作为输入设备的程序,这意味着我需要将焦点放在文本框上.

I have a program which uses a barcode scanner as input device so that means I need to keep the focus on a text box.

该程序有一个列表视图控件,当扫描某个条码时,我以编程方式选择其中一个项目.我通过以下方式设置行的背景颜色:

The program has a listview control and I select one of the items programatically when a certain barcode is scanned. I set the background color of the row by:

listviewitem.BackColor = Color.LightSteelBlue;

我尝试过的事情:

  • listview.HideSelection 设置为 false
  • 设置颜色后调用listview.Focus()
  • listviewitem.Focused 设置为 true
  • 调用 listview.Invalidate
  • 调用listview.Update()
  • 调用listview.Refresh()
  • 以上的不同组合
  • listview.HideSelection set to false
  • call listview.Focus() after setting the color
  • listviewitem.Focused set to true
  • call listview.Invalidate
  • call listview.Update()
  • call listview.Refresh()
  • different combinations of the above

我还在计时器中组合了上述内容,以便在不同的线程上调用它们,但仍然没有成功.

I've also did combinations above stuff in a timer so that they are called on a different thread but still no success.

有什么想法吗?

更多信息:

  • 这里的关键是控制焦点.当我选择其中一项时,listview 控件没有焦点.
  • 我通过以下方式选择了一项:

  • The key here is the control focus. The listview control does not have the focus when I select one of the items.
  • I select one item by doing:

listView1.Items[index].Selected = true;

  • 焦点始终在文本框中.

  • the Focus is always in the textbox.

    我有这个代码来保持对文本框的关注:

    I have this code to keep the focus on the textbox:

    private void txtBarcode_Leave(object sender, EventArgs e)
    {
       this.txtBarcode.Focus();
    }
    

    你需要有一个文本框添加该代码来模拟我的问题.

    You need to have a textbox add that code to simulate my problem.

    推荐答案

    您描述的内容完全按预期工作,假设您已设置 HideSelectionListView 控件的 属性设置为 False.这是用于演示目的的屏幕截图.我创建了一个空白项目,在表单中添加了一个 ListView 控件和一个 TextBox 控件,在 ListView 中添加了一些示例项,设置了它的视图到详细信息"(尽管这适用于任何视图),并将 HideSelection 设置为 false.我处理了 TextBox.Leave 事件,就像你在问题中展示的那样,并添加了一些简单的逻辑来选择相应的 ListViewItem 每当它的名称输入到 TextBox 中时.注意在ListView中选择了Test Item Six":

    What you describe works exactly as expected, assuming that you've set the HideSelection property of the ListView control to False. Here's a screenshot for demonstration purposes. I created a blank project, added a ListView control and a TextBox control to a form, added some sample items to the ListView, set its view to "Details" (although this works in any view), and set HideSelection to false. I handled the TextBox.Leave event just as you showed in the question, and added some simple logic to select the corresponding ListViewItem whenever its name was entered into the TextBox. Notice that "Test Item Six" is selected in the ListView:

        

         

    现在,正如我最初怀疑的那样,如果你自己设置 BackColor 属性,你会把事情搞砸.我不确定您为什么要这样做,因为默认情况下控件已经使用默认选择颜色来指示所选项目.如果您想使用不同颜色,您应该更改您的 Windows 主题,而不是尝试编写代码来实现.

    Now, as I suspected initially, you're going to mess things up if you go monkeying around with setting the BackColor property yourself. I'm not sure why you would ever want to do this, as the control already uses the default selection colors to indicate selected items by default. If you want to use different colors, you should change your Windows theme, rather than trying to write code to do it.

    事实上,如果我在我现有的代码之外添加行 item.BackColor = Color.LightSteelBlue 来选择 ListViewItem 对应于键入到 TextBox,我得到完全与上面显示的相同的东西.在您将焦点设置到控件之前,项目的背景颜色不会更改.这是预期的行为,因为选定的项目在获得焦点时与父控件未获得焦点时看起来不同.焦点控件上的选定项目使用系统高亮颜色绘制;未聚焦控件上的选定项目使用系统 3D 颜色绘制.否则,将无法判断 ListView 控件是否具有焦点.此外,当 ListView 控件具有焦点时,操作系统会完全忽略任何自定义 BackColor 属性.背景以默认的系统高亮颜色绘制.

    In fact, if I add the line item.BackColor = Color.LightSteelBlue in addition to my existing code to select the ListViewItem corresponding to the name typed into the TextBox, I get exactly the same thing as shown above. The background color of the item doesn't change until you set focus to the control. That's the expected behavior, as selected items look different when they have the focus than they do when their parent control is unfocused. Selected items on focused controls are painted with the system highlight color; selected items on unfocused controls are painted with the system 3D color. Otherwise, it would be impossible to tell whether or not the ListView control had the focus. Moreover, any custom BackColor property is completely ignored by the operating system when the ListView control has the focus. The background gets painted in the default system highlight color.

    将焦点显式设置到 ListView 控件,当然会导致自定义背景颜色应用于 ListViewItem,并且事物呈现的颜色非常与我在计算机上选择的配色方案形成对比(请记住,并非每个人都使用默认值).但是,问题立即变得显而易见:您无法将焦点设置到 ListView 控件,因为您在 TextBox.Leave 中编写了代码事件处理方法!

    Explicitly setting the focus to the ListView control, of course, causes the custom background color to be applied to the ListViewItem, and things render with a color that very much contrasts with the color scheme that I've selected on my computer (remember, not everyone uses the defaults). The problem, though, becomes immediately obvious: you can't set the focus to the ListView control because of the code you've written in the TextBox.Leave event handler method!

    我现在可以告诉你,在焦点改变事件中设置焦点是错误的做法.在 Windows 中这是一条硬性规定,你不能做这样的事情,文档 甚至明确警告您不要这样做.据推测,您的答案将类似于我必须",但这不是借口.如果一切都按预期进行,您一开始就不会问这个问题.

    I can tell you right now that setting the focus in a focus-changing event is the wrong thing to do. It's a hard rule in Windows you're not allowed to do things like that, and the documentation even warns you explicitly not to do it. Presumably, your answer will be something along the lines of "I have to", but that's no excuse. If everything were working as expected, you wouldn't be asking this question in the first place.

    那么,现在怎么办?您的应用程序设计已损坏.我建议修复它. 不要试图自己设置 BackColor 属性来指示选择了一个项目.它与 Windows 突出显示所选项目的默认方式相冲突.另外,不要尝试在焦点更改事件中设置焦点.Windows 明确禁止这样做,并且文档清楚地表明您不应该这样做.如果目标计算机没有鼠标或键盘,首先不清楚用户将如何将焦点设置为其他任何东西,除非您编写代码来执行此操作,而您不应该这样做.

    So, what now? Your application's design is broken. I suggest fixing it. Don't try and monkey with setting the BackColor property yourself to indicate that an item is selected. It conflicts with the default way that Windows highlights selected items. Also, don't try and set the focus in a focus-changing event. Windows explicitly forbids this, and the documentation is clear that you're not supposed to do this. If the target computer doesn't have a mouse or keyboard, it's unclear how the user is going to set focus to anything else in the first place, unless you write code to do it, which you shouldn't be doing.

    但令人惊讶的是,我几乎不相信您会想要修复您的应用程序.忽略文档中警告的人往往就是不听问答网站上善意建议的人.所以我会扔给你一块骨头,告诉你无论如何如何获得你想要的效果.关键是不要设置ListViewItemSelected属性,避免你自定义的BackColor和系统默认高亮的冲突 它还使您不必将焦点显式设置到 ListView 控件并再次返回(正如我们在上面建立的,鉴于您的 离开 事件处理程序方法).这样做会产生以下结果:

    But I have surprisingly little faith that you'll want to fix your application. People who ignore warnings in the documentation tend to be the same people who don't listen to well-meaning advice on Q&A sites. So I'll throw you a bone and tell you how to get the effect you desire anyway. The key lies in not setting the ListViewItem's Selected property, which avoids the conflict between your custom BackColor and the system default highlight color. It also frees you from having to explicitly set the focus to the ListView control and back again (which, as we established above, isn't actually happening, given your Leave event handler method). Doing that produces the following result:

        

         

    这是代码 - 它不是很漂亮,但这只是概念证明,而不是最佳实践示例:

    And here's the code—it's not very pretty, but this is just a proof of concept, not a sample of best practice:

    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();
       }
    }
    

    这篇关于即使关注另一个控件,如何更改列表视图选定行的背景色?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆