I use the AvalonEdit.TextDocument control. Now I want to get the current text-selection/textmark from it. But the class implments no any convenient property or method.
How I can get the current text selection from AvalonEdit.TextDocument?
PS: It does not really make much sense here to add some code from my app
The easiest way I found to deal with selections with an AvalonEdit editor is as follows:
IEnumerable<SelectionSegment> selectionSegments = Editor.TextArea.Selection.Segments;
TextDocument document = Editor.TextArea.Document;
foreach (SelectionSegment segment in selectionSegments)
{
//DO WHAT YOU WANT WITH THE SELECTIONS
int lineStart = document.GetLineByOffset(segment.StartOffset).LineNumber;
int lineEnd = document.GetLineByOffset(segment.EndOffset).LineNumber;
for (int i = lineStart; i <= lineEnd; i++)
{
//Do something with each line in the selection segment
}
}
In my case I needed to mark something on each line selected, so that's why I split it into lines.
Related
I'm updating some old code that loops over a collection and sets some UI display properties based on the values in the object.
Unfortunately, it's hardcoded like so:
for (int i = 0 ; i < length; i++) // length is going to be 30+
{
// do some stuff
switch (i)
{
case 1:
lbl1.Text = myVariable;
break;
case 2:
lbl2.Text = myVariable;
break;
....
case 15:
lbl15.Text = myVariable;
break;
}
}
(I say unfortunately because it actually has 5 more lines per case that I left out, which do the exact same thing regardless of the case)
Now, I could put all 15 label controls in an array and in my for loop just do if (i <= 15) lblArr[i].Text = myVariable; but I'd prefer not to have to hardcode this array. If we add more labels then we'll need to remember to update this function.
So, I'm trying to find a way to find all the controls within a particular HTML element, but I cannot find a working example in a .NET language.
In winforms I could simply just iterate over someControl.Controls and find the appropriate ones, but since these are labels in an HTML table and not a repeater or anything like that I don't know how to find them. Any ideas?
You can use the FindControl method :
for (int i = 0 ; i < length; i++)
{
Label ans = FindControl(string.Format("lbl{0}",i)) as Label ;
if (ans!=null) and.Text = myVariable
}
How about jquery? It's definteily much faster than .NET. give it a shot... :)
$(function () {
var myTableId = "yourTableId";
var yourReplacementText = "yourReplacementText";
var allSpansUnderYourTable = $('#' + myTableId).find('span');
$.each(allSpan, function (index, item) {
item.innerHTML = yourReplacementText;
});
});
Depending on the complexity of the code, it may be cleaner to just retrieve a db row on page load, set it to a property on the codebehind (or put its data in an object that is a property on the page), and then bind to it using code blocks. You can get rid of all of the <asp:Label> elements that way too.
e.g.
<table>
<tr>
<td><span><%: myObject.Property1 %></span></td>
</tr>
</table>
That way you can make all of your binding declarative and remove the need for procedural codebehind logic to loop through and set things.
I've stored a list of colors in my program. I am after an object in my scene to one of the colors in the list. So far, I have done the followings:
if(Input.GetKeyDown(KeyCode.O))
{
for(int i = 0; i < claddingColor.Count; i++)
{
claddingMaterial.color = claddingColor[i];
}
}
This isn't working due to a reason I know (and you can probably spot) but I lack to the verbal fortitude to write it down.
As opposed to have a multiple lines of the following:
claddingMaterial.color = claddingColor[0];
Each tied to different buttons, I like a way I can emulate the above but tie it to a single button press. Thus, if I hit the 0 button 5 times, it will loop through each color stored in the list. If I hit it for a sixth time, it will go back to the first color in the list.
Could someone please help me implement this? Or point me to something that I may learn how to do it for myself?
Define LastColor property as class member:
int LastColor;
In your function use modulo
if(Input.GetKeyDown(KeyCode.O))
{
claddingMaterial.color = claddingColor[(LastColor++) % claddingColor.Count];
}
Note: Depending on the type of claddingColor use Count for a List or Length for Array.
You won't need a for loop
int lastStep = 0;
if(Input.GetKeyDown(KeyCode.O))
{
claddingMaterial.color = claddingColor[lastStep++];
if (lastStep == claddingColor.Count)
lastStep = 0;
}
I have a C# application in which there are several textboxes with the same name except for a number on the end which starts at 1 and goes to 19. I was hoping to use a for loop to dynamically add values to these text boxes by using an arraylist. There will be situations where there will not be 19 items in the arrayList so some text boxes will be unfilled. Here is my sample code for what I am trying to do. Is this possible to do?
for (int count = 0; count < dogList.Count; count++)
{
regUKCNumTextBox[count+1].Text=(dogList[count].Attributes["id"].Value.ToString());
}
So you've got a collection of text boxes that are to be filled out top-to-bottom? Then yes, a collection of TextBox seems appropriate.
If you stick your TextBox references in an array or a List<TextBox> -- I wouldn't use an ArrayList as it's considered deprecated in favor of List<T> -- then yes, you can do that:
TextBox[] regUKCNumTextBox = new []
{
yourTextBoxA,
yourTextBoxB,
...
};
Then yes your logic is possible, you can also query the control by it's name, though that would be heavier at runtime - so it's a tradeoff. Yes, in this solution you must set up a collection to hold your text box references, but it will be more performant.
Try this:
(By the way I am assuming you use WinForms)
for (int count = 0; count < dogList.Count; count++)
{
object foundTextBox = this.Controls.Find("nameofTextBoxes" + [count+1]);
if (foundTextBox != null)
{
if (foundTextBox is TextBox)
{
((TextBox)foundTextBox).Text=(dogList[count].Attributes["id"].Value.ToString());
}
}
}
With this code you are trying to find a Control form your Forms Controls collection. Then you have to make sure the control is of the TextBox type. When it is; cast it to a TextBox and do what you want with it. In this case; assign a value to the Text property.
It would be more efficient to keep a collection of your TextBoxes like in the solution offered by James Michael Hare
Yikes; something doesn't seem quite right with the overall design there; but looking past that, here's a quick stab at some pseudo code that might work:
for (int count = 0; count < dogList.Count; count++)
{
var stringName = string.Format("myTextBoxName{0}", count);
var ctrl = FindControl(stringName);
if(ctrl == null) continue;
ctrl.Text = dogList[count];
}
The incredibly awesome AvalonEdit WPF TextEditor control seems to lack an important feature, or at least i can't figure it out. Given an offset and a length, highlight that portion in the TextDocument with a HighlightColor. Simple, right?
Apprentely not. I've RTFM, and the documentation on "Syntax Highlighting" confused me even more. Someone else asked the same question in the SharpDevelop forums, and i'm afraid i can't make sense of Herr Grunwald's answer.
Here's my attempt, using the DocumentHighlighter class (of course it doesn't work):
textEditor1.Text = "1234567890";
HighlightingColor c = new HighlightingColor() { FontWeight = FontWeights.ExtraBold };
DocumentHighlighter dh = new DocumentHighlighter(textEditor1.Document, new HighlightingRuleSet());
HighlightedLine hl = dh.HighlightLine(1);
hl.Sections.Add(new HighlightedSection() { Color = c, Offset = 1, Length = 3 });
Thank you for helping!
Did you see this in this article - it seems to be exactly what are you asking for:
public class ColorizeAvalonEdit : DocumentColorizingTransformer
{
protected override void ColorizeLine(DocumentLine line)
{
int lineStartOffset = line.Offset;
string text = CurrentContext.Document.GetText(line);
int start = 0;
int index;
while ((index = text.IndexOf("AvalonEdit", start)) >= 0) {
base.ChangeLinePart(
lineStartOffset + index, // startOffset
lineStartOffset + index + 10, // endOffset
(VisualLineElement element) => {
// This lambda gets called once for every VisualLineElement
// between the specified offsets.
Typeface tf = element.TextRunProperties.Typeface;
// Replace the typeface with a modified version of
// the same typeface
element.TextRunProperties.SetTypeface(new Typeface(
tf.FontFamily,
FontStyles.Italic,
FontWeights.Bold,
tf.Stretch
));
});
start = index + 1; // search for next occurrence
} } }
It highlights word AvalonEdit with bold.
Some background info:
AvalonEdit is a code editor, not a rich text editor. There is no such thing as "highlight a portion of the document" - the document only stores plain text.
Highlighting is computed on-demand, only for the lines currently in view. If you want custom highlighting, you need to add a step to the highlighting computation - this is what the ColorizeAvalonEdit class in the example posted by mzabsky is doing.
You need to create a custom ColorizingTransformer to do that. The above example is actually highlighting a specific word. Still, you can change it a little bit to to colorize or highlight a portion.
I used Avalon TextEditor for my Console+ project (which is in a very primitive stage at the moment)
public class OffsetColorizer : DocumentColorizingTransformer
{
public int StartOffset { get; set; }
public int EndOffset { get; set; }
protected override void ColorizeLine(DocumentLine line)
{
if (line.Length == 0)
return;
if (line.Offset < StartOffset || line.Offset > EndOffset)
return;
int start = line.Offset > StartOffset ? line.Offset : StartOffset;
int end = EndOffset > line.EndOffset ? line.EndOffset : EndOffset;
ChangeLinePart(start, end, element => element.TextRunProperties.SetForegroundBrush(Brushes.Red));
}
}
And you can add the colorizer to the editor by adding it to LineTransformers collection.
tbxConsole.TextArea.TextView.LineTransformers.Add(_offsetColorizer);
I know this is a pretty old question, but I thought I would share my solution. I am not sure if this solution has been implemented into AvalonEdit, since this question was originally answered, but I find the OffsetColorizer class doesn't actually select the line: it just changes the line's background colour.
My solution is as follows:
textEditor.SelectionStart = offset;
textEditor.SelectionLength = length;
However, this can be extended further like so:
public void SelectText(int offset, int length)
{
//Get the line number based off the offset.
var line = textEditor.Document.GetLineByOffset(offset);
var lineNumber = line.LineNumber;
//Select the text.
textEditor.SelectionStart = offset;
textEditor.SelectionLength = length;
//Scroll the textEditor to the selected line.
var visualTop = textEditor.TextArea.TextView.GetVisualTopByDocumentLine(lineNumber);
textEditor.ScrollToVerticalOffset(visualTop);
}
I find that this solution works better is that rather than just colouring the line, it actually selects it: meaning it can be copied using Ctrl+C.
I Hope this helps people in the future.
Is there a way to remove an item from a listbox based on a string?
I have been playing around for a few minutes and here is what i have so far but its not working
foreach(string file in LB_upload.Items)
{
ftp.Upload(file);
int x = LB_upload.Items.IndexOf(file);
LB_upload.Items.RemoveAt(x);
}
I could just loop through each item but I wanted to do something a little more elegant
while(LB_upload.Items.Count > 0)
{
ftp.Upload(LB_upload.Items[0].ToString());
LB_upload.Items.RemoveAt(0);
}
Based on your example, I'd do something like;
foreach(string file in LB_upload.Items)
{
ftp.Upload(file);
}
LB_upload.Items.Clear();
The problem you are probably encountering is that you are altering the list while iterating over this. This is a big no-no, and has been covered ad-nauseum on this site.
Based on the title of your question it sounds like you don't want to remove every item, just some of them. If that's the case:
for (int i = LB_upload.Items.Count - 1; i >= 0; i--)
{
if (somecondition)
{
ftp.Upload(LB_upload.Items[i]);
LB_upload.Items.RemoveAt(i);
}
}