Text With Superscript In MigraDoc - c#

I have a class for writing a PDF doc via MigraDoc.
A function makes a call like this:
var p = row.Cells[1].AddParagraph();
p.AddLineBreak();
p.AddLineBreak();
_renderHtml(office["Address"], p.AddFormattedText());
The _renderHtml code looks like this:
private void _renderHtml(string html, FormattedText text)
{
_renderHtmlElement(
new Html.Parsable("dom", html),
text
);
}
The _renderHtmlElement code then does a series of checks for what HTML to actually handle. I'm thinking I should throw it into a switch case, but that doesn't really affect my question. So it looks like this:
private void _renderHtmlElement(Html.Element element, FormattedText text)
{
if ("p" == element.Type)
{
//do stuff
}
else if ("li" == element.Type)
{
//do stuff
}
else if ("b" == element.Type || "strong" == element.Type)
{
text = text.AddFormattedText(TextFormat.Bold);
}
else if ("i" == element.Type || "em" == element.Type)
{
text = text.AddFormattedText(TextFormat.Italic);
}
else if ("br" == element.Type || "em" == element.Type)
{
text.AddLineBreak();
}
else if ("text" == element.Type)
{
//do stuff
}
else if("sup" == element.Type)
{
FormattedText ft = text.AddFormattedText(element.ContentDecoded);
ft.Superscript = true;
}
foreach (var child in element.ChildElements)
{
_renderHtmlElement(child, text);
}
}
My piece is to get the superscript code working. The code I have in there now will add in the correct content, formatted as a superscript, but it then still has the original content (not superscripted) immediately following it. The methods of text seem to only allow add functions, there's no replace or substring or anything similar for me to just tear out the second instance.
Am I overlooking something obvious here? As you can see from the bold/italic examples, it's a fairly straight forward process, so I would think I'm just not passing in the text.superscript properly.
Any and all help would be greatly appreciated.
Cheers

You add the Superscript text, then you call _renderHtmlElement for the children - maybe a child gives you the same text, but without superscript attribute.
Are there other tags between <sup> and </sup> in your HTML?
MigraDoc has Remove methods so you can remove items - but better not to add them in the first place.
I'd put a breakpoint on "ft.Superscript = true;" and check what _renderHtmlElement does for the children of the "sup" element.

Related

Finding which textbox is empty

I have short windows program I use to add information quickly. But now I'm trying to enhance it.
Was looking for a more efficient want to check for empty text boxes and if the box was empty to find which one it was and set the focus back to only that box. Currently I loop through all of them and check to see if any box was empty if it is just display a message. But have to look to see which box is missing text. Heres the code:
bool txtCompleted = true;
string errorMessage = "One or more items were missing from the form";
foreach(Control c in Controls)
{
if (c is TextBox)
{
if (String.IsNullOrEmpty(c.Text))
{
txtCompleted = false;
}
}
}
if (txtCompleted == false)
{
MessageBox.Show(errorMessage);
}
Your approach using foreach looks promising to me. Howver you can use LINQ as well
if(this.Controls.OfType<TextBox>().Any(t => string.IsNullOrEmpty(t.Text)) {
...
}
You can use the focus() method to set the focus to the empty text box.
Set the focus on the control while in your loop, then break when done.
foreach(Control c in Controls)
{
if (c is TextBox)
{
if (String.IsNullOrEmpty(c.Text))
{
txtCompleted = false;
c.Focus();
MessageBox.Show(errorMessage);
break;
}
}
}
To get a reference to the empty textbox you use almost the same solution as R.T. presents, but use FirstOrDefault instead:
var emptyTextBox = Controls.OfType<TextBox>().FirstOrDefault(t => string.IsNullOrEmpty(t.Text)
if (emptyTextBox != null)
{
// there is a textbox that has no Text set
// set focus, present error message etc. on emptyTextBox
}

How do I fill a textbox in webkitbrowser?

I have this code for a textbox on a website:
<textarea class="chat_input">
Enter text for chat here
</textarea>
What I am trying to do, is to put text into it. On a different question, a person showed how to click a link that was a class with this code:
foreach (Node el in webKitBrowser1.Document.GetElementsByTagName("a"))
{
if (((Element) el).GetAttribute("id") == "lnkId")
{
string urlString = ((Element) el).Attributes["href"].NodeValue;
webKitBrowser1.Navigate(urlString);
}
}
I tried adapting it for this code here:
message = txtMessage.Text;
foreach(Node txt in wb.Document.GetElementsByTagName("textarea"))
{
if(((Element)txt).GetAttribute("Class") == "chat_input")
{
((Element)txt).SetAttribute("Value", message);
}
}
When I debugged it, it went though the code 5 times, which is how many textarea's there was. Does anyone know why it does not fill the textbox?
You need to not use SetAttribute, but set the TextContent property instead.
So:
if(((Element)txt).GetAttribute("Class") == "chat_input")
{
((Element)txt).TextContent = message;
}

How could I check if a textbox has text?

I'm trying to make an if statement to check whether a TextBox has text it.
So something like this:
if (textbox1 has text)
{
//Then do this..
}
How would I write "textbox1 has text"?
if (textbox1.Text.Length > 0)
{
...
}
or
if (!string.IsNullOrEmpty(textbox1.Text))
{
...
}
You can get the text stored in the TextBox using Text property of the TextBox and then check whether it is null or empty like this :-
string text = textBox1.Text ;
if(String.IsNullOrEmpty(text))
{
// Do something
}
Check the length of the text box text.
if (textbox1.Text.Length > 0)
{
//do the process here
}
Please try
if(!string.IsNullOrWhiteSpace(textbox1.Text))
{
//
}
Checking the Length
if (textBox1.Text.Length > 0)
{
// perform task
}
Using the Null
if (!string.IsNullOrEmpty(textBox1.Text))
{
// perform a task
}
Using Trim would be nice for checking if a user is only putting spaces.
if (textBox1.Text.Trim().Length > 0)
{
// perform a task
}
Try any one of these and it should work. There are way more ways but since this question is a bit broad it's up to you.
Simple. Check out this MSDN page: string.IsNullOrEmpty
if (!string.IsNullOrEmpty(textBox1.Text))
{
}
Alternatively, you could use a property. This is especially helpful when you need to check multiple times to see if the textbox has text:
// a public property is not necessary for this
bool HasText
{
get
{
return !string.IsNullOrEmpty(textBox1.Text);
}
}
...
if (HasText)
{
}
Another way to go about doing this is by using an extension method:
public static class TextBoxUtility
{
public static bool HasText(this TextBox textBox)
{
return !string.IsNullOrEmpty(textBox.Text);
}
}
...
if(textBox1.HasText())
{
}
I prefer the latter instead of a property because it works across all textboxes.
the simpliest logic is this:
if (textBox1.Text != "")
MessageBox.Show("The textbox is not empty!");
else
MessageBox.Show("The textbox is empty!");
I have seen all the other answers on the page, suggesting solutions like
if (tb.Text == "")
{
// Is empty
} else {
// Is not empty
}
However this could easily break, and return that a text box is not empty, when it actually is. For example, a few spaces in the text box (and nothing else) would pass as not empty, when in fact, while not technically empty, you would probably want to report it as empty. A solution to this is the C# string.Trim() method. This removed all whitespace. Now changing my solution to this:
if (tb.Text.Trim() == "")
{
// Is empty
} else {
// Is not empty
}
... it would no longer report a text box full with spaces as not empty.
if(textBox1.Text!=null)
{
///code
}
or
if(textBox1.Text!=string.Empty)
{
//code
}
if(textbox.Text.Trim().Length > 0)
{
// Do something
}

How to Make RichTextBox Text Only? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to prevent richTextBox to paste images within it?
If you're using Richtextbox, there are several advantages in Richtextbox for example:
we can use color font on it
Setting custom font in a region
Attach files on it.. etc
take a look at the picture:
Here is my problem:
Can i just make it text only?
In my project, attach file or the like is unnecessary at all. I even didn't want attach or paste an images on it, i just want "text only" on Richtextbox
How can i do that?
Since RichTextBox doesn't have a Images or Objects collection you have to go for the RTF formatting codes. All data of RichTextBox is stored as plain text with special formatting codes, this is exposed by the control through its RTF property. Learning this code language is essential if you want to read or change it, learning resources are easily available throughout the web, see for example this overview. RichTextBox uses more simplified rtf codes than several full-feature editors like MS Word etc, so it is usually beneficial to load data into a RTB before manipulating it, this will remove much redundant data.
Making a long story short, I found that it is necessary to search for rtf groups that start with either "pict" or "object" command. Knowing that groups may be nested you can't just find the first end-group char from there, you have to parse the string char by char while keeping count of grouping to find the end of those groups. Now you have enough information to remove that part of the string. Rtf may contain multiple picture/object groups so you have to do this until all are removed. Here is a sample function that return rtf string after removing those groups:
private string removeRtfObjects(string rtf)
{
//removing {\pict or {\object groups
string pattern = "\\{\\\\pict|\\{\\\\object";
Match m = Regex.Match(rtf, pattern);
while (m.Success) {
int count = 1;
for (int i = m.Index + 2; i <= rtf.Length; i++) {
//start group
if (rtf(i) == '{') {
count += 1;
//end group
} else if (rtf(i) == '}') {
count -= 1;
}
//found end of pict/object group
if (count == 0) {
rtf = rtf.Remove(m.Index, i - m.Index + 1);
break; // TODO: might not be correct. Was : Exit For
}
}
m = Regex.Match(rtf, pattern);
//go again
}
return rtf;
}
When should this be done? You have already mention Paste, there is also Insert, these can be trapped with the KeyDown event where you get the clipboard info and handle it accordingly. Setting e.Handled=True when you have handled the operation yourself signals that the control should not do any default processing for this key combination. This is also how you block pasting images without destroying the users clipboard. Example:
private void RichTextBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
//aware of Paste or Insert
if (e.Control && e.KeyCode == Keys.V || e.Shift && e.KeyCode == Keys.I) {
if (Clipboard.ContainsImage || Clipboard.ContainsFileDropList) {
//some images are transferred as filedrops
e.Handled = true;
//stops here
} else if (Clipboard.ContainsData(DataFormats.Rtf)) {
RichTextBox rtbox = new RichTextBox();
//use a temp box to validate/simplify
rtbox.Rtf = Clipboard.GetData(DataFormats.Rtf);
this.RichTextBox1.SelectedRtf = this.removeRtfObjects(rtbox.Rtf);
rtbox.Dispose();
e.Handled = true;
}
}
}
Yes, it is possible.
Handle Ctrl+V in RichTextBox1_KeyDown, then check the data format in the Clipboard: if data is plain text, paste it; if data is RTF, convert it to plain text (in a buffer without changing the Clipboard content) and paste it; don't paste any other type of data.
This is a partial example just to show you how to proceed:
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.V)
{
// suspend layout to avoid blinking
richTextBox2.SuspendLayout();
// get insertion point
int insPt = richTextBox2.SelectionStart;
// preserve text from after insertion pont to end of RTF content
string postRTFContent = richTextBox2.Text.Substring(insPt);
// remove the content after the insertion point
richTextBox2.Text = richTextBox2.Text.Substring(0, insPt);
// add the clipboard content and then the preserved postRTF content
richTextBox2.Text += (string)Clipboard.GetData("Text") + postRTFContent;
// adjust the insertion point to just after the inserted text
richTextBox2.SelectionStart = richTextBox2.TextLength - postRTFContent.Length;
// restore layout
richTextBox2.ResumeLayout();
// cancel the paste
e.Handled = true;
}
}

How can I check multiple textboxes if null or empty without a unique test for each?

I have about 20 text fields on a form that a user can fill out. I want to prompt the user to consider saving if they have anything typed into any of the text boxes. Right now the test for that is really long and messy:
if(string.IsNullOrEmpty(txtbxAfterPic.Text) || string.IsNullOrEmpty(txtbxBeforePic.Text) ||
string.IsNullOrEmpty(splitContainer1.Panel2) ||...//many more tests
Is there a way I could use something like an Array of any, where the array is made of the text boxes and I check it that way? What other ways might be a very convenient way in which to see if any changes have been made since the program started?
One other thing I should mention is there is a date time picker. I don't know if I need to test around that as the datetimepicker will never be null or empty.
EDIT:
I incorporated the answers into my program, but I can't seem to make it work correctly.
I set up the tests as below and keep triggering the Application.Exit() call.
//it starts out saying everything is empty
bool allfieldsempty = true;
foreach(Control c in this.Controls)
{
//checks if its a textbox, and if it is, is it null or empty
if(this.Controls.OfType<TextBox>().Any(t => string.IsNullOrEmpty(t.Text)))
{
//this means soemthing was in a box
allfieldsempty = false;
break;
}
}
if (allfieldsempty == false)
{
MessageBox.Show("Consider saving.");
}
else //this means nothings new in the form so we can close it
{
Application.Exit();
}
Why is it not finding any text in my text boxes based on the code above?
Sure -- enumerate through your controls looking for text boxes:
foreach (Control c in this.Controls)
{
if (c is TextBox)
{
TextBox textBox = c as TextBox;
if (textBox.Text == string.Empty)
{
// Text box is empty.
// You COULD store information about this textbox is it's tag.
}
}
}
Building on George's answer, but making use of some handy LINQ methods:
if(this.Controls.OfType<TextBox>().Any(t => string.IsNullOrEmpty(t.Text)))
{
//Your textbox is empty
}
public void YourFunction(object sender, EventArgs e) {
string[] txtBoxArr = { textBoxOne.Text, textBoxTwo.Text, textBoxThree.Text };
string[] lblBoxArr = { "textBoxOneLabel", "textBoxTwoLabel", "textBoxThreeLabel" };
TextBox[] arr = { textBoxOne, textBoxTwo, textBoxThree };
for (int i = 0; i < txtBoxArr.Length; i++)
{
if (string.IsNullOrWhiteSpace(txtBoxArr[i]))
{
MessageBox.Show(lblBoxArr[i] + " cannot be empty.");
arr[i].Focus();
return;
}
}
}

Categories