views:

253

answers:

5

I'm trying to work my way through Ron Jeffries's Extreme Programming Adventures in C#. I am stuck, however, in Chapter 3 because the code does not, and cannot, do what the author says it does.

Basically, the text says that I should be able to write some text in a word-wrap enabled text box. If I then move the cursor to an intermediate line and hit enter, the code should re-display the lines before the cursor, add a couple of lines and a set of HTML paragraph tags, then append the rest of the lines. The code doesn't match the text because it uses the textbox.lines property. Well, no matter how many word-wrapped lines there are in a text box, there's only ONE line in the Lines property until you hit a carriage return. So, the statement that the code should, "Copy the rest of the lines into the buffer" appears wrong to me.

I'd appreciate anybody having experience with the book telling me what I'm reading, or doing, wrong!

Thanks.

EoRaptor

A: 

Not answering my own question but speculating:

I think the author may be cutting and pasting text into his application, and only then, trying to insert paragraph tags. That way, he can get two textbox.lines without having to actually use the enter key.

Or so it seems to me...

EoRaptor013
A: 

May we see the code please?

Loophole
+1  A: 

Try emailing Ron Jeffries directly. I have the book - somewhere, but I don't remember it not working. His email address is ronjeffries at acm dot org and put [Ron] in the subject line.

(And for those wondering - his email info was right from his website Welcome page)

Cory Foy
Thanks. I thought of that, but I wanted to make sure I wasn't going to look any stupider than I really am before contacting the author! ;-)
EoRaptor013
A: 
print("using System;

using System.Collections; using System.Collections.Generic; using System.Text;

namespace NotepadOne {

public class TextModel {

private String[] lines;
private int selectionStart;
private int cursorPosition;

public TextModel() {

}

public String[] Lines {
  get {
    return lines;
  }
  set {
    lines = value;
  }
}

public int SelectionStart {
  get {
    return selectionStart;
  }
  set {
    selectionStart = value;
  }
}

public int CursorPosition {
  get {
    return cursorPosition;
  }
  set {
    cursorPosition = value;
  }
}

public void InsertControlPText() {
  lines[lines.Length - 1] += "ControlP";
}

public void InsertParagraphTags() {
  int cursorLine = CursorLine();
  String[] newlines = new String[lines.Length + 2];
  for (int i = 0; i <= cursorLine; i++) {
    newlines[i] = lines[i];
  }
  newlines[cursorLine + 1] = "";
  newlines[cursorLine + 2] = "<P></P>";
  for (int i = cursorLine + 1; i < lines.Length; i++) {
    newlines[i + 2] = lines[i];
  }
  lines = newlines;
  selectionStart = NewSelectionStart(cursorLine + 2);
}

private int CursorLine() {
  int length = 0;
  int lineNr = 0;
  foreach (String s in lines) {
    if (length <= SelectionStart && SelectionStart <= length + s.Length + 2) {
      break;
      length += s.Length + Environment.NewLine.Length;
      lineNr++;
    }
    lineNr++;
  }
  return lineNr;
}

private int NewSelectionStart(int cursorLine) {
  int length = 0;
  for (int i = 0; i < cursorLine; i++) {
    length += lines[i].Length + Environment.NewLine.Length;
  }
  return length + 3;
}

} } ");

The InsertParagraphTags method is called by pressing the enter key in the textbox.

BTW, the break here is that there is a subscript out of range error if you try to hit enter at the end of the text. I'm sure I could figure out how to get around this but then my code won't look like his code; which is what I'm trying to learn.

Randy

EoRaptor013
+1  A: 

I've also just started this book and had exactly the same problem although the code you have included looks further along than where I am. The 'subscript out of range' occurred for 2 reasons, first as Ron explains he was just testing and so returned a hard-coded value of 3 before he wrote the CursorLine() function, which means you I think at least 4? lines of text which as you say need to be pasted in, or maybe set the text to this value before running, also as you say they need to have carriage returns to make txtbox.Lines return an array of strings. The second reason occurs even after CursorLine() has been implemented but only happens if the text box is empty as txtbox.Lines returns string[0] but I think Ron is implementing a 'User Story' which says that when text has been entered and user presses enter, so not sure if he fixes this later, but will probably find out!

The author's do state that they are learning C# and will show the development wart's and all, which is one of the reasons I have chosen to study this book as I think it is encouraging me to develop projects. I also try to do the code first before looking at his solutions to see if I'm thinking the same way, but maybe I know C# a little better than I give myself credit for, or I'm completly crap, but I've noticed a few things, first he says that overriding OnKeyDown() doesn't work, but I think he must have got confused and tried to do in Form, instead of deriving from TextBox and overriding there. This was my code when reading the 'User Story':

int curPos = txtbox.SelectionStart;
string Wrd = Environment.NewLine + "<P></P>" + Environment.NewLine;              
txtbox.SelectedText = Wrd;
int pl = Environment.NewLine.Length + 3; // "<P>" length is 3
// Put text cursor inbetween <P> tags
txtbox.SelectionStart = curPos + pl;

It works differently to Ron's code, but was just my interpretation of the 'User Story' and not sure how should act if text is selected or wether to split line if text cursor in the middle etc.

Also in 'My Adventures' in Extreme Programming Adventures in C#

txtbox.GetLineFromCharIndex(txtbox.SelectionStart)

gets the cursor line position and doesn't matter if no carriage returns or resized, as far as I can tell, I done little test with:

txtbox.GetLineFromCharIndex(txtbox.TextLength)

which returns the total amount of lines, which will vary if you resize the text box.

Using C# I always look for solutions which already exsist and people may slate me for this but I think MS have created a great language with great components which do what you expect them to do, so don't have to re-create the wheel each time. Although like I say it's early days in this book and perhaps these simple solutions aren't extensible enough and maybe Ron's taking that into account, although he did mention just get it working then worry about that later is more the XP way.

Warren.

Knightlore