大家还是先来看看效果吧

这次之所以一次写两个控件,其实主要是因为Label控件实在是太简单了没有必要放放一个文章里写,所以就一次性来了。
Label控件我就不再多说了,我直接把代码贴一下吧因为就几行代码,相信大家一眼就能看明白了。

代码

using System;
using System.Collections.Generic;

using System.Text;

namespace CRD.WinUI.Misc
{
public class Label:System.Windows.Forms.Label
{
public Label()
: base()
{
this.BackColor = System.Drawing.Color.Transparent;
}
}
}

ListBox实现

咱们从第一行代码就要吧看出来是继承自系统控件而来的。
public class ListBox : System.Windows.Forms.ListBox
所以本身就具备了系统的ListBox的一些特性。老方法我们先来看看WndProc方法的实现

代码

protected override void WndProc(ref System.Windows.Forms.Message m)
{
IntPtr hDC = IntPtr.Zero;
Graphics gdc = null;

switch (m.Msg)
{
case 133:
hDC = Win32.GetWindowDC(m.HWnd);
gdc = Graphics.FromHdc(hDC);
Win32.SendMessage(this.Handle, WM_ERASEBKGND, hDC.ToInt32(), 0);
SendPrintClientMsg();
Win32.SendMessage(this.Handle, WM_PAINT, 0, 0);
OverrideControlBorder(gdc);
m.Result = (IntPtr)1;
Win32.ReleaseDC(m.HWnd, hDC);
gdc.Dispose();
break;
case WM_PAINT:
base.WndProc(ref m);
hDC = Win32.GetWindowDC(m.HWnd);
gdc = Graphics.FromHdc(hDC);
OverrideControlBorder(gdc);
Win32.ReleaseDC(m.HWnd, hDC);
gdc.Dispose();
break;
default:
base.WndProc(ref m);
break;
}
}

这边的实现方法基本上和之前的控件一个样,所以我就不再多说原理了,大家随便看一下前几次的文章就明白了。
下面我们来看一下怎么样换皮肤的事件
也就是说在换皮肤的时候我们应该做那些工作

代码

protected override void OnDrawItem(DrawItemEventArgs e)
{
Graphics g = e.Graphics;
//绘制区域
Rectangle r = e.Bounds;

Font fn = null;
if (e.Index >= 0)
{
if (e.State == DrawItemState.None)
{
//设置字体、字符串格式、对齐方式
fn = e.Font;
string s = (string)this.Items[e.Index];
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
//根据不同的状态用不同的颜色表示
if (e.State == (DrawItemState.NoAccelerator | DrawItemState.NoFocusRect))
{
e.Graphics.FillRectangle(new SolidBrush(Color.Red), r);
e.Graphics.DrawString(s, fn, new SolidBrush(Color.Black), r, sf);
e.DrawFocusRectangle();
}
else
{
e.Graphics.FillRectangle(new SolidBrush(Color.White), r);
e.Graphics.DrawString(s, fn, new SolidBrush(Shared.FontColor), r, sf);
e.DrawFocusRectangle();
}
}
else
{
fn = e.Font;
StringFormat sf = new StringFormat();
sf.Alignment = StringAlignment.Near;
string s = (string)this.Items[e.Index];
e.Graphics.FillRectangle(new SolidBrush(Shared.ControlBackColor), r);
e.Graphics.DrawString(s, fn, new SolidBrush(Shared.FontColor), r, sf);
}
}
}

其实这些都不是今天要说的重点,这个控件的实现基础跟之前的一些控件基本上是一样的,像Textbox就和这个差不多,
唯一我想说的是滚动条的实现,不多说了下面开始吧

滚动条的实现

如上面的图片大家已经看到了,图片在我的源代码里都有,我在这里就不多说了,一起来看是怎么实现 的吧,先说说思路,
第一步,先制做一个自己的滚动条,随便做只要自己感觉漂亮就可以,第二步就是,利用Api把Listbox现有的滚动条用现在的滚动条代替,第三步,让现有的滚动条和系统的滚动条实现同步即可。
我实现滚动条的代码,大家也可以自己写这里只是一个参考吧
看一下效果

看一下代码吧,具体的素材大家到我源代码里面找吧,呵呵

代码

关于一些Api的方法吧,我都定义出来了直接用就行了

代码

public class Win32API
{
[StructLayout(LayoutKind.Sequential)]
public struct tagSCROLLINFO
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}

public enum fnBar
{
SB_HORZ = 0,
SB_VERT = 1,
SB_CTL = 2
}
public enum fMask
{
SIF_ALL,
SIF_DISABLENOSCROLL = 0X0010,
SIF_PAGE = 0X0002,
SIF_POS = 0X0004,
SIF_RANGE = 0X0001,
SIF_TRACKPOS = 0X0008
}

public static int MakeLong(short lowPart, short highPart)
{
return (int)(((ushort)lowPart) | (uint)(highPart << 16));
}
public const int SB_THUMBTRACK = 5;
public const int WM_HSCROLL = 0x114;
public const int WM_VSCROLL = 0x115;
[DllImport("user32.dll", EntryPoint = "GetScrollInfo")]
public static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO lpsi);
[DllImport("user32.dll", EntryPoint = "SetScrollInfo")]
public static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref SCROLLINFO lpsi, bool fRedraw);

[DllImport("User32.dll", CharSet = CharSet.Auto, EntryPoint = "SendMessage")]
static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, long wParam, int lParam);
}

最后一步控件同步效果

代码
SCROLLINFO info = tvImageListScrollInfo;
info.nPos = customScrollbar1.Value;
Win32API.SetScrollInfo(listBox1.Handle, (int)ScrollBarDirection.SB_VERT, ref info, true);
Win32API.PostMessage(listBox1.Handle, Win32API.WM_VSCROLL, Win32API.MakeLong((short)Win32API.SB_THUMBTRACK, (short)(info.nPos)), 0);

好了,现在我们拉一个控件到窗体上,就是我图1中的效果了。中间还有一些不好的地方,我争取改正,
也希望大家多多提建议,
我个人感觉这种方法不是什么很好的方法,如果是用C++来写的话会方便很多,但不知道c#是怎么写的,小弟确实不知道,还希望能得大家的帮助,一起来解决这个问题
其实我在网上也找了不少的资料,有些方法清空是抄别别人的,不过效果是实现 的,但总是感觉 不理想,不是自己想要的,也希望能通过这篇文章收集到一些好的解决方案,欢迎大家提供资源和解决方法,小弟在些谢过。
-------------------------------------------------------------签名部分------------------------------------------------------------------------

欢迎大家转载,如有转载请注明文章来自: http://sufei.cnblogs.com/
签名:做一番一生引以为豪的事业;在有生之年报答帮过我的人;并有能力帮助需要帮助的人;
软件开发,功能定制,请联系我

QQ:361983679 Email:sufei.1013@163.com MSN:sufei.1013@163.com

-------------------------------------------------------------------推荐文章--------------------------------------------------------------
1.C#仿QQ皮肤 2.Sql2005学习笔记 3.httpHelper类

C#仿QQ皮肤-Label与ListBox 控件实现----寻求滚动条的解决方案的更多相关文章

  1. ListBox控件

    主要介绍:自定义数据.绑定数据库数据 前台代码: <div> <asp:ListBox ID=" Width ="100px"> <asp: ...

  2. SilverLight:基础控件使用(2)-ComboBox,ListBox控件

    ylbtech-SilverLight-Basic-Control:基础控件使用(2)-ComboBox,ListBox控件 直接在 XAML 代码中设置 Items 和通过后台代码绑定数据源 Com ...

  3. asp.net中的ListBox控件添加双击事件

    问题:在Aspx页里的ListBox A中添加双击事件,将选中项添加到另一个ListBox B中,双击ListBox B中的选中项,删除当前选中项 页面: <asp:ListBox ID=&qu ...

  4. WPF中ListBox控件在选择模式(SelectionMode)为Single时仍然出现多个Item被选中的问题

    最近在学习WPF过程中使用到了ListBox控件,在使用时遇到下面的奇怪问题: 代码如下: listBox.Items.Add("绘图"); listBox.Items.Add(& ...

  5. MATLAB GUI程序设计中ListBox控件在运行期间消失的原因及解决方法

    在运行期间,ListBox控件突然消失,同时给出如下错误提示: Warning: single-selection listbox control requires that Value be an ...

  6. MFC中Listbox控件的简单使用

    MFC中listbox控件是为了显示一系列的文本,每个文本占一行.   Listbox控件可以设置属性为: LBS_CHILD   :(默认)子窗口 LBS_Visible :(默认)可视 LBS_M ...

  7. 异步方式向WPF ListBox控件中一条一条添加记录

    向ListBox绑定数据源时,如果数据量过大,可能会使得程序卡死,这是就需要一条一条的向ListBox的数据源中添加记录了,下面是个小Demo: 1.前台代码,就是一个ListBox控件 <Wi ...

  8. asp.net Listbox控件用法

    2008-02-18 19:56 来源: 作者: ListBox(列表框)控件可以显示一组项目的列表,用户可以根据需要从中选择一个或多个选项.列表框可以为用户提供所有选项的列表.虽然也可设置列表框为多 ...

  9. ASP.NET中ListBox控件的使用

    文章来源:http://www.cnblogs.com/fengzheng126/archive/2012/04/10/2441551.html ListBox控件属性介绍: SelectIndex: ...

随机推荐

  1. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_06 Set集合_3_HashSet集合存储数据的结构

    特点就是查询速度快 jdk1.8以后,如果链表的长度超过了8位.就会把转成红黑树,也是为了提高查询的效率

  2. 通过命令直接修改jar包中的静态文件

    1.先将要修改的jar包备份 copy xxx.jar xxx.jar_bak 2.建立一个新的目录便于后面的打包 mkdir jar_tmp 3.将包放到刚刚创建的目录里解压 mv xxx.jar ...

  3. linux中常用的60个命令及作用详解

    Linux 必学的 60 个命令 Linux 提供了大量的命令,利用它可以有效地完成大量的工作,如磁盘操作.文件存取.目录操作.进程管理.文件权限设定等.所以,在 Linux 系统上工作离不开使用系统 ...

  4. java Map与Bean相互转化

    import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector ...

  5. Spring MVC-学习笔记(3)参数绑定注解、HttpMessageConverter<T>信息转换、jackson、fastjson、XML

    1.参数绑定注解 1>@RequestParam: 用于将指定的请求参数赋值给方法中的指定参数.支持的属性: 2>@PathVariable:可以方便的获得URL中的动态参数,只支持一个属 ...

  6. 配置sde使可以使用sde sql(ST_Geometry)操作空间数据

    用处:进行此配置后,可以用sql语言,与sde空间数据库进行空间查询,增删改图层的要素等 PS:同时也是解决 ORA-28595Extproc 代理 DLL 路径无效 的方法 ORA-06512: 在 ...

  7. A.Gennady and a Card Game

    http://m3.codeforces.com/contest/1097/problem/A Gennady and a Card Game time limit per test 1 second ...

  8. 反射、getattr

    #coding=utf-8 class Dog(object): def __init__(self,name): self.name = name def eat(self): print '123 ...

  9. markdown简介及基本语法

    一.前言 Markdown是一种轻量级标记语言,它以纯文本形式(易读.易写.易更改)编写文档,并最终以HTML格式发布. Markdown也可以理解为将以MARKDOWN语法编写的语言转换成HTML内 ...

  10. jquery点击按钮弹出图片

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...