 |
|
|
 |
|
 |
too complicate and not fully functional (scrolling)
|
|
|
|
 |
|
 |
Hi, I tried pasting some japanese text, it seems the line numbering cannot support other than latin characters. Any idea how to fix this?
|
|
|
|
 |
|
 |
<code>private void DrawLines(Graphics g, int firstLine)
{
// Number of text lines
int linesCount = richTextBox.Lines.Length;
// Last visible line (used to determine numbers panel width)
int lastChar = this.richTextBox.GetCharIndexFromPosition(new Point(this.richTextBox.ClientRectangle.Width, this.richTextBox.ClientRectangle.Height));
int lastLine = this.richTextBox.GetLineFromCharIndex(lastChar);
// Line numbers layout (position, width)
int rightMargin = 2, leftMargin = 5, topMargin = 2, bottomMargin = 15, verticalMargin = 2;
SizeF maxTextSize = g.MeasureString(new string((char)48, lastLine.ToString().Length), this.richTextBox.Font);
this.panelNum.Width = (int)maxTextSize.Width + leftMargin + rightMargin;
// Clear existing numbers
g.Clear(this.panelNum.BackColor);
// First line name
int lineNumber = firstLine + 1;
// Y position for first line number
int firstLineY = this.richTextBox.GetPositionFromCharIndex(this.richTextBox.GetFirstCharIndexFromLine(firstLine)).Y;
int lineY = topMargin + firstLineY;
// Write all visible line numbers
while (true)
{
// Draw line number string
string lineNumberLabel = lineNumber.ToString().PadLeft(lastLine.ToString().Length);
g.DrawString(lineNumberLabel, this.richTextBox.Font, Brushes.Black, leftMargin, lineY);
// Next line
lineNumber += 1;
lineY += Font.Height + verticalMargin;
// End of numeration if and of text content or end of RichTextBox height
if (lineY > ClientRectangle.Height - bottomMargin || lineNumber > linesCount)
break;
}
}</code>
Note: I'm using a Panel Control to display the line numbers (Dock = Left, Fill for RichTextBox)
|
|
|
|
 |
|
 |
Would you provide some source code as a attachment?
kr, zara
|
|
|
|
 |
|
 |
I can put a bullet in the indent column! why not a line number?
Great job to all! best ive seen yet.
|
|
|
|
 |
|
 |
Hi!
Can somebody tel me how to delete a linenumber when using two richtextbox?
thanks
|
|
|
|
 |
|
 |
I'm using the code in .Net 3.5, and I dont know if in others version its happens, but the first line when the scroll bar is visible, the numbers are not synchronized with the lines... the problem is that the first line number is the 1 but int firstIndex = editor.GetCharIndexFromPosition(pos) returned 0...
the solution is just change
Point pos = new Point(0, 0)
to
Point pos = new Point(0, 1).
|
|
|
|
 |
|
 |
Your solution really helped me a lot.Thank you!
However, I found some problems. First,Only 16 lines for line number can be displayed although code in richTextBox1 is more than 16 lines. What's more, the text and line number are not aligned well.
I'm sure you can solve the probelm.
ChenQiang
Thank you!
|
|
|
|
 |
|
 |
Remove the following line in the NumberedTextBoxUC.designer.cs
this.numberLabel.Size = new System.Drawing.Size(37, 267);
and replace it by the following line:
this.numberLabel.AutoSize = true;
You can also speed up the controller by assigning the numberLabel.Text only once in the updateNumberLabel(). Construct a string containing the new label and then assign it once done.
Rod
|
|
|
|
 |
|
 |
Petr,
My text editor will be considerable larger than your demo. The RichTextBox and Label resize properly, however, the line numbers are only painted on the label as far as the original height. Can you suggest a fix for this?
Thanks,
Jim
|
|
|
|
 |
|
 |
Petr,
Never mind, I fixed it. After:
//this is point position of last visible char, we'll use its Y value for calculating numberLabel size
pos = rtb.GetPositionFromCharIndex(lastIndex);
I added:
numberLabel.Size = new Size(numberLabel.Width, pos.Y + (int) rtb.Font.GetHeight());
I also inserted the following before the above, for when the insertion point is on a new line after the last character:
if (rtb.SelectionLength == 0)
{
int idx = rtb.SelectionStart;
if (idx > lastIndex) lastIndex = idx;
}
And all is well!:
Jim
|
|
|
|
 |
|
 |
First of all, thanks for the control, great job.
The easiest way to get rid of the label fontsize vs richtextbox font-size is to assign the same font for both controls and set the AutoScaleMode to None for the NumberedTextBoxUC (Properties->Layout->AutoScaleMode)
Hope this helps
|
|
|
|
 |
|
 |
Simple and easy to understand!
Mike
Theres light at the end of the tunnel. Lord I hope it ain't no train!
|
|
|
|
 |
|
 |
I used the following to disable smooth scrolling:
class myRichTextBox : RichTextBox
{
private const short WM_SCROLL = 0x115;
private const UInt32 SB_THUMBPOSITION = 4;
private const UInt32 SB_THUMBTRACK = 5;
protected override void WndProc(ref Message m)
{
if(m.Msg == WM_SCROLL)
{
UInt32 wparam = (UInt32)m.WParam;
UInt32 type = wparam & 0x0000FFFF;
UInt32 pos = (wparam & 0xFFFF0000) >> 16;
if (type == SB_THUMBPOSITION || type == SB_THUMBTRACK)
{
pos = pos - (pos % ((UInt32)this.Font.Height+1));
}
wparam = (pos << 16) + type;
m.WParam = (IntPtr)wparam;
base.WndProc(ref m);
}
}
}
|
|
|
|
 |
|
 |
Great Code!
Here's an enhancement for no smooth wheelscroll:
[DllImport("user32.dll")]
private static extern bool GetScrollInfo(IntPtr hwnd, int fnBar, ref SCROLLINFO ScrollInfo);
struct SCROLLINFO
{
public int cbSize;
public UInt32 fMask;
public Int32 nMin;
public Int32 nMax;
public UInt32 nPage;
public Int32 nPos;
public Int32 nTrackPos;
}
public enum ScrollInfoMask
{
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS
}
private const short WM_MOUSEWHEEL = 522;
private const int SB_PAGEDOWN = 3;
private const int SB_PAGEUP = 2;
if (m.Msg == WM_MOUSEWHEEL)
{
int rotation = (int)m.WParam / 0x0000FFFF;
int pos;
int lines = SystemInformation.MouseWheelScrollLines;
if (lines > 0)
{
SCROLLINFO info = new SCROLLINFO();
info.cbSize = Marshal.SizeOf(info);
info.fMask = (int)ScrollInfoMask.SIF_ALL;
GetScrollInfo(this.Handle, SB_VERT, ref info);
if (rotation > 0)
{
pos = info.nPos - (this.Font.Height + 1) * lines;
}
else
{
pos = info.nPos + (this.Font.Height + 1) * line
}
pos = Math.Max(0, pos << 16);
m.WParam = (IntPtr)(SB_THUMBPOSITION | pos);
}
else
{
if (rotation > 0)
{
m.WParam = (IntPtr)SB_PAGEUP;
}
else
{
m.WParam = (IntPtr)SB_PAGEDOWN;
}
}
m.Msg = WM_SCROLL;
base.WndProc(ref m);
}
|
|
|
|
 |
|
 |
Merci beaucoup....
Thank'a lot....
Grazie mille....
Muchos gracias....
pline
|
|
|
|
 |
|
 |
to complete the final piece i added a scroll bar to the bottom of my version of the control but i cant seem to get the right properties for setting the propper width of the content...ie hscroll.maximum = ?????? your line numbering trick rocks so far, thanks..
|
|
|
|
 |
|
 |
Great article, best I found on the subject!
Just one small thing, you mention that the a lot of problems can be solved by setting the scroll increments to a whole line width. Any pointers as to how I could do this?
Cheers
Paul
|
|
|
|
 |
|
 |
Don't Use a Label, instead use another TextBox (Multiline) Or Another RichEditBox, either way you solve your font problem. Otherwise good job!!!
-Wayne
|
|
|
|
 |
|
 |
Dont use a TextBox nor an RichTextbox, just paint it on an empty panel.
It is so much faster. Here some destilled code from my project
protected override void OnPaint(PaintEventArgs e)
{
.....
Point pos = new Point(0, 0);
int firstIndex = this.rt1.GetCharIndexFromPosition(pos);
int firstLine = this.rt1.GetLineFromCharIndex(firstIndex);
Font font = this.rt1.Font;
int LineHeight = 16; // use your own height
int lastLine = firstLine +
(int)(this.rt1.ClientRectangle.Height / LineHeight));
int delta = this.rt1.GetPositionFromCharIndex(0).Y % (font.Height + 1);
e.Graphics.Clear(this.BackColor);
for (int i = firstLine; i < lastLine; i++)
e.Graphics.DrawString(string.Format("{0:0000}", i + 1),
font, brush,
new PointF(0F, delta + (i - firstLine) * LineHeight));
.....
}
|
|
|
|
 |
|
 |
Thanks alphons.
I did it, but don't work again.
Can you put your project here.
Thanks to you
|
|
|
|
 |
|
 |
From a bigger project, this is what I use.
using System;
using System.Drawing;
using System.Windows.Forms;
namespace SomeNameSpace
{
public partial class Numbered : UserControl
{
public RichTextBox richTextBox1;
private Brush brush;
public float LineHeight;
public Numbered()
{
InitializeComponent();
this.SetStyle(
ControlStyles.DoubleBuffer |
ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint,
true);
this.UpdateStyles();
brush = new SolidBrush(this.ForeColor);
LineHeight = 0.0F;
}
private void updateNumberLabel(PaintEventArgs e)
{
if (this.brush == null)
return;
if (this.ClientSize.Width <= 0 || this.ClientSize.Height <= 0)
return;
int delta = 0;
int firstLine = 0;
int lastLine = 10;
Font font = this.Font;
if (this.richTextBox1 == null)
{
LineHeight = 16.0F;
}
else
{
Point pos = new Point(0, 0);
int firstIndex = this.richTextBox1.GetCharIndexFromPosition(pos);
firstLine = this.richTextBox1.GetLineFromCharIndex(firstIndex);
font = this.richTextBox1.Font;
if (LineHeight < 0.01)
{
if (this.richTextBox1.Lines.Length > 1)
{
Point pos1 = this.richTextBox1.GetPositionFromCharIndex(this.richTextBox1.GetFirstCharIndexFromLine(1));
LineHeight = pos1.Y;
}
}
lastLine = Math.Min(this.richTextBox1.Lines.Length, 2 + firstLine + (int)(this.richTextBox1.ClientRectangle.Height / LineHeight));
int intCharIndex = this.richTextBox1.GetCharIndexFromPosition(Point.Empty);
delta = 1 + this.richTextBox1.GetPositionFromCharIndex(intCharIndex).Y % font.Height;
}
lastLine = Math.Max(lastLine, 1);
Graphics g = e.Graphics;
g.Clear(this.BackColor);
if(this.richTextBox1==null)
g.SetClip(new Rectangle(0, 0, this.Width, this.Height));
else
g.SetClip(new Rectangle(0, 0, this.Width, this.richTextBox1.ClientRectangle.Height));
for (int i = firstLine; i < lastLine; i++)
g.DrawString(string.Format("{0 ###}", i + 1), font, brush,
new PointF(0F, delta + (i - firstLine) * LineHeight) );
}
protected override void OnPaint(PaintEventArgs e)
{
updateNumberLabel(e);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
}
}
}
Your have to make some hooks to trigger the painting when
scrolling, or changing font etc.
On the richtextbox this can be done by using code like this:
protected override void OnVScroll(EventArgs e)
{
base.OnVScroll(e);
this.numbered1.Invalidate();
}
|
|
|
|
 |
|
 |
It's great.
Thanks alphons.
|
|
|
|
 |
|
 |
protected override void OnVScroll(EventArgs e)
{
base.OnVScroll(e);
this.numbered1.Invalidate();
}
where do i place this code?...
i try it for a long time... :(
|
|
|
|
 |