首先效果图:
百度网盘下载地址:http://pan.baidu.com/s/1gdlCZ4J
CSDN下载地址:http://download.csdn.net/detail/crystal_lz/8155323
因为最近需要素以写了一个 如果控件只是单纯的显示数据 不用选中什么的到是很好处理 直接g.DrawString绘制出来就是了 但是这里我全部是用的TextRenderer.DrawText() 因为貌似TextRenderer绘制文本的时候 可以带上文本背景色这样绘制选中文本就方便了 虽然可以用DrawRectangle和DrawString达到同样效果 但是太麻烦了感觉 但是很遗憾貌似TextRenderer在指定颜色的时候A通道无效 也是就是说无法绘制透明效果的文字来着 不过算了 没有人会设置透明的文字颜色吧
说说思路吧 首先你得有数据吧?所以控件必然有个属性为byte[]类型 而控件需要做的就是将这个byte数组的数据绘制出来 如同刚才上面说的 如果只是展示不需要选中什么的 很好处理 直接DrawString就行了每行取出byte数组的十六个数据:
g.DrawString(addr.ToString("X").PadLeft(8,'0') + " " + BitConverter.ToString(byte[],index,len).Replace('-',' ') + " " + Encoding.ASCII.GetString(byte[],index,len));差不多就是上面的代码 但是由于这里我需要选中 所以我要知道我鼠标点下的时候 在那个数据上 所以我需要知道每个绘制的数据的坐标 所以我的做法就是 每个数据每个数据的绘制 虽然影响效率不过也没啥了 所以我在代码中放了两个变量:
// 16进制数据每个字符的偏移量 protected int[] m_nArrHexLeftOffset; // ASCII数据每个字符的偏移量 protected int[] m_nArrAscLeftOffset;两个的长度都是16 分别保存十六进制和ASCII字符所需要绘制的X坐标 Y坐标我不需要保存因为有字体的Height属性 没绘制一行Y坐标+=一个字体的Height就行了 鼠标点击的时候 也可以知道点击在第几行的字上面 所以绘制的代码我是差不度这样的:
/// <summary> /// 绘制16进制数据 /// </summary> /// <param name="g">绘图设备</param> protected virtual void DrawHex(Graphics g) { int len = this._TopLineStartIndex + m_nLinesForDraw; if (len > m_nLineCount) len = m_nLineCount; for (int i = this._TopLineStartIndex; i < len; i++) { string strDraw = (this._StartAddr + i * 16).ToString("X").PadLeft(8, '0') + " "; //g.DrawString(strDraw, this.Font, Brushes.Blue, this._LeftOffset, (i - this._TopLineStartIndex + 1) * this.Font.Height); TextRenderer.DrawText(g, strDraw, this.Font, new Point(this._LeftOffset, (i - this._TopLineStartIndex + 1) * this.Font.Height), this._AddrColor); int index = i * 16; for (int j = 0; j < 16; j++) { Color clrHexForeColor = this._HexForeColor; Color clrHexBackColor = Color.Transparent; Color clrASCIIForeColor = this._ASCIIForeColor; Color clrASCIIBackColor = Color.Transparent; if (index == this._SelectedDataIndex) { clrHexForeColor = this._HexHighForeColor; clrHexBackColor = this._HexHighBackColor; clrASCIIForeColor = this._ASCIIHighForeColor; clrASCIIBackColor = this._ASCIIHighBackColor; } else if (index >= this._SelectionStartIndex && index <= this._SelectionEndIndex) { clrHexForeColor = this._HexSelectedForeColor; clrHexBackColor = this._HexSelectedBackColor; clrASCIIForeColor = this._ASCIISelectedForeColor; clrASCIIBackColor = this._ASCIISelectedBackColor; } TextRenderer.DrawText(g, this._ByteData[index].ToString("X").PadLeft(2, '0'), this.Font, new Point(m_nArrHexLeftOffset[j] + this._LeftOffset, (i - this._TopLineStartIndex + 1) * this.Font.Height), clrHexForeColor, clrHexBackColor); TextRenderer.DrawText(g, ((char)(this._ByteData[index] == 0 ? (byte)'.' : this._ByteData[index])).ToString(), this.Font, new Point(m_nArrAscLeftOffset[j] + this._LeftOffset, (i - this._TopLineStartIndex + 1) * this.Font.Height), clrASCIIForeColor, clrASCIIBackColor); if (++index == this._ByteData.Length) return; } } }
其他具体细节自己看源码吧