C#仿QQ皮肤-Label与ListBox 控件实现----寻求滚动条的解决方案
大家还是先来看看效果吧
这次之所以一次写两个控件,其实主要是因为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 控件实现----寻求滚动条的解决方案的更多相关文章
- ListBox控件
主要介绍:自定义数据.绑定数据库数据 前台代码: <div> <asp:ListBox ID=" Width ="100px"> <asp: ...
- SilverLight:基础控件使用(2)-ComboBox,ListBox控件
ylbtech-SilverLight-Basic-Control:基础控件使用(2)-ComboBox,ListBox控件 直接在 XAML 代码中设置 Items 和通过后台代码绑定数据源 Com ...
- asp.net中的ListBox控件添加双击事件
问题:在Aspx页里的ListBox A中添加双击事件,将选中项添加到另一个ListBox B中,双击ListBox B中的选中项,删除当前选中项 页面: <asp:ListBox ID=&qu ...
- WPF中ListBox控件在选择模式(SelectionMode)为Single时仍然出现多个Item被选中的问题
最近在学习WPF过程中使用到了ListBox控件,在使用时遇到下面的奇怪问题: 代码如下: listBox.Items.Add("绘图"); listBox.Items.Add(& ...
- MATLAB GUI程序设计中ListBox控件在运行期间消失的原因及解决方法
在运行期间,ListBox控件突然消失,同时给出如下错误提示: Warning: single-selection listbox control requires that Value be an ...
- MFC中Listbox控件的简单使用
MFC中listbox控件是为了显示一系列的文本,每个文本占一行. Listbox控件可以设置属性为: LBS_CHILD :(默认)子窗口 LBS_Visible :(默认)可视 LBS_M ...
- 异步方式向WPF ListBox控件中一条一条添加记录
向ListBox绑定数据源时,如果数据量过大,可能会使得程序卡死,这是就需要一条一条的向ListBox的数据源中添加记录了,下面是个小Demo: 1.前台代码,就是一个ListBox控件 <Wi ...
- asp.net Listbox控件用法
2008-02-18 19:56 来源: 作者: ListBox(列表框)控件可以显示一组项目的列表,用户可以根据需要从中选择一个或多个选项.列表框可以为用户提供所有选项的列表.虽然也可设置列表框为多 ...
- ASP.NET中ListBox控件的使用
文章来源:http://www.cnblogs.com/fengzheng126/archive/2012/04/10/2441551.html ListBox控件属性介绍: SelectIndex: ...
随机推荐
- 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_08 Map集合_9_Hashtable集合
是最早期的双列集合 同步就表示是单线程 value也不允许为空
- string与wstring的互相转换接口(Windows版本)
string与wstring的互相转换接口(Windows版本) std::wstring stringToWstring( const std::string & str ) { LPCST ...
- 时间同步,使用oracle自带的ctss
crsctl check ctss --observer mode cluvfy comp clocksync -检查crss为啥没启用 根据不同版本删除ntp的配置和服务 AIX: stops ...
- 模块内高内聚?模块间低耦合?MVC+EF演示给你看!
前言 在软件项目开发过程中,我们总能听见“高内聚,低耦合”,即使这种思想在我们学习编程的过程中就已经耳濡目染.可一旦当我们上项目,赶进度的时候我们就会“偷懒”,能省时间就省.管他什么设计模式,什么软件 ...
- 如何让cmd启动始终以管理员身份运行(方法已失效)
神来之图--实测以下方法已经不能使用,辗转看了好多文章,内容基本如下图,不知道谁转的谁的,总之已经是不能用的文章了.在此记录一下.至于解决办法目前没有找到,之前随笔中有提到新建一个cmd命令提示符的快 ...
- JavaSE编码试题强化练习2
1.编写递归算法程序:一列数的规则如下: 0.1.1.2.3.5.8.13.21.34...... 求数列的第40位数是多少. public class TestRecursion { public ...
- hdu-2819.swap(二分匹配 + 矩阵的秩基本定理)
Swap Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- JVM-堆内存
1. java堆内存介绍 java的堆内存可以类比于计算机的内存,是存储整个机器数据的地方. (1)jvm一起动就创建java堆.类比计算机一起动就加载内存. (2)所有的线程共享.类比计算机所有进程 ...
- 在WebStorm中使用editorConfig插件
在webStorm中默认是支持editorConfig插件的,那么我们需要在webStorm中自定义editorConfig的配置怎么来做? 第一步:打开webStrome > File > ...
- 2019牛客暑期多校训练营(第五场) - C - generator 2 - BSGS
https://ac.nowcoder.com/acm/contest/885/C 这个跟平时那种求离散对数的bsgs不一样,虽然可以转化成离散对数来做不过会T掉.展开递推式然后合并具有a的项,发现其 ...