吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1101|回复: 3
收起左侧

[求助] C# winform ,以自定义userControl作为listbox的item,drawItem的DrawFocusRectangle

[复制链接]
ilovecomputer66 发表于 2023-3-10 23:25
C# winform ,以自定义userControl作为listbox的item,drawItem的DrawFocusRectangle作用是选中某项,这一项就会框起来

但我发现一个很诡异的问题。如果form中只有listbox这一个控件,就没有问题,选中的会被框起来

但如果随便加个控件,比如下面代码中一个button,点击选中也不会有加框效果,当然,获取selectedItemIndex还是正确的

但不知道为什么会是这样的表现了


111.png form的代码

[C#] 纯文本查看 复制代码
namespace CSharpDemo.Demo.MyItemInControl
{
    public partial class MyItemInListBoxForm : Form
    {
        public MyItemInListBoxForm()
        {
            InitializeComponent();

            // 此绘制模式下,才可以自己决定每项的高度
            Lst.DrawMode = DrawMode.OwnerDrawVariable;

            Lst.Height = (int)(new UserControlItem().Height * 2.5f);
            Lst.Width = new UserControlItem().Width;
        }

        private void MyItemInListBoxForm_Load(object sender, EventArgs e)
        {
            {
                UserControlItem itemControl = new UserControlItem();
                itemControl.UserName = "张三";
                itemControl.UserPost = "会计";
                itemControl.UserPhoto = Color.Red;

                Lst.Items.Add(itemControl);
            }
            {
                UserControlItem itemControl = new UserControlItem();
                itemControl.UserName = "李四";
                itemControl.UserPost = "出纳";
                itemControl.UserPhoto = Color.Green;

                Lst.Items.Add(itemControl);
            }
            {
                UserControlItem itemControl = new UserControlItem();
                itemControl.UserName = "王五";
                itemControl.UserPost = "预算";
                itemControl.UserPhoto = Color.Blue;

                Lst.Items.Add(itemControl);
            }
            {
                UserControlItem itemControl = new UserControlItem();
                itemControl.UserName = "赵六";
                itemControl.UserPost = "经理";
                itemControl.UserPhoto = Color.Yellow;

                Lst.Items.Add(itemControl);
            }
            {
                UserControlItem itemControl = new UserControlItem();
                itemControl.UserName = "孙七";
                itemControl.UserPost = "保安";
                itemControl.UserPhoto = Color.Purple;

                Lst.Items.Add(itemControl);
            }
        }

        private void Lst_DrawItem(object sender, DrawItemEventArgs e)
        {
            if (e.Index >= 0 && e.Index < Lst.Items.Count)
            {
                // 获取要绘制的自定义UserControl
                UserControlItem control = (UserControlItem)Lst.Items[e.Index];
                // 创建一个大小与自定义UserControl相同的Bitmap
                Bitmap bitmap = new Bitmap(control.Width, control.Height);
                // 将自定义UserControl绘制到Bitmap中
                control.DrawToBitmap(bitmap, new Rectangle(0, 0, control.Width, control.Height));
                // 绘制Bitmap到ComboBox中
                e.Graphics.DrawImage(bitmap, e.Bounds);

                // 绘制选中项获取焦点时的矩形区域
                e.DrawFocusRectangle();
            }
        }

        private void Lst_MeasureItem(object sender, MeasureItemEventArgs e)
        {
            // 获取要测量的自定义UserControl
            UserControlItem control = (UserControlItem)Lst.Items[e.Index];
            // 设置项的高度为自定义UserControl的高度
            e.ItemHeight = control.Height;
        }

        private void BtnGetSelectedItem_Click(object sender, EventArgs e)
        {
            if (Lst.SelectedIndex < 0)
                MessageBox.Show("没有选中任何项");
            else
                MessageBox.Show($"选中项的index为:{Lst.SelectedIndex},对应姓名为{(Lst.SelectedItem as UserControlItem).UserName}");
        }
    }
}



自定义userControl的代码
[C#] 纯文本查看 复制代码
namespace CSharpDemo.Demo.MyItemInControl
{
    public partial class UserControlItem : UserControl
    {
        public UserControlItem()
        {
            InitializeComponent();
        }

        public string UserName
        {
            get { return LblName.Text; }
            set { LblName.Text = value; }
        }

        public string UserPost
        {
            get { return LblPost.Text; }
            set { LblPost.Text = value; }
        }

        public Color UserPhoto
        {
            get { return PicPhoto.BackColor; }
            set { PicPhoto.BackColor = value; }
        }
    }
}




发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

s2690170 发表于 2023-3-10 23:53
chatgpt的回答,你可以试试
这个问题可能是由于控件绘制顺序的问题导致的。在WinForms中,每个控件都有一个绘制顺序,即ZOrder。绘制顺序决定了控件在屏幕上的覆盖顺序,即后绘制的控件会覆盖先绘制的控件。

在你的代码中,ListBox和Button都是在同一个容器(Form)中,它们的绘制顺序取决于它们添加到容器中的顺序。如果ListBox在Button之前添加到容器中,那么ListBox会先绘制,这时你选中项会被正确地框起来。但如果Button在ListBox之前添加到容器中,那么Button会先绘制,导致ListBox的选中项框不被正确地绘制。
Lst.BringToFront();
这样就可以确保ListBox的选中项框会正确地绘制。

解决这个问题的一种方法是将ListBox的绘制顺序提高到比Button更高。你可以使用ListBox的BringToFront方法将ListBox移动到容器的顶部。在MyItemInListBoxForm的构造函数中添加以下代码:
 楼主| ilovecomputer66 发表于 2023-3-11 08:33
s2690170 发表于 2023-3-10 23:53
chatgpt的回答,你可以试试
这个问题可能是由于控件绘制顺序的问题导致的。在WinForms中,每个控件都有一 ...

我也是先问的chatgpt,每次回复都不相同。但兄弟收到的这个回复,应该是它没听懂你描述的意思。显然不是这样

它误解成,你给他描述的是因为控件重叠导致,所以它让你把它放最上面。但我实际问题并不是这个,所以也无用

它回复我的有3种不同的答案,但都试过没用
1、把userControl用代码设置为可以获得焦点
2、点击listbox中的item,用代码强制lst.force()
3、drawitem中判断force就画DrawFocusRectangle(当然,这个最不靠谱,我没判断,任何情况都画都画不出来)
Broadm 发表于 2023-3-11 11:06
还是 wpf来的简单, winform 烦的很, 界面又丑代码也啰嗦, 最重要的是搞个自定义控件太麻烦, 还一丢问题
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-25 02:29

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表