How to delete text from RichTextBox and add a Run in the deleted position

Emon Haque 3,176 Reputation points
2021-10-12T06:31:38.377+00:00

The SQLite database browsing tools which I've used so far either doesn't have good support for mixed text (LTR + RTL) in query editor or good intellisense. So for convenience, as I'm analyzing Quranic words (Arabic), I've decided to create one for that purpose. So far I've been able to do these kind of things:

139751-x1.gif

Here all that I did is typed a few letter and hit 'TAB' or selected a ListBoxItem from popup ListBox then hit TAB and it inserted and colorized those syntax in right place. Right now, the issue is, if I don't hit TAB those syntax get the last color I set, as you can see at the end of the animated GIF. Thing that I want is ,when I hit space: delete the last word and insert a colorized Run in that place. When I hit TAB on query editor (RichTextBox) or on ListBox, this function is called:

void setToken() {  
    suggestion.IsOpen = false;  
    var key = (FunKey)FunKeys.CurrentItem;  
    if (key is null) return;  
    var para = txtQuery.CaretPosition.Paragraph;  
    var tokens = new TextRange(para.ContentStart, para.ContentEnd).Text.Split(" ");  
    para.Inlines.Clear();  
    foreach (var token in tokens) {  
        if (token.Equals("")) continue;  

        string text = "";  
        for (int i = 0; i < token.Length; i++) {  
            if (charTokens.Contains(token[i])) {  
                if (text != "") {  
                    setRun(text, token[i]);  
                    text = "";  
                }  
                var str = token[i].ToString();  
                var run = new Run(str);  
                if (token[i].Equals(')')) run.Text += " ";  
                setNormalStyle(run, getTag(str));  
                para.Inlines.Add(run);  
            }  
            else text += token[i];  
            if (i == token.Length - 1 && !text.Equals("")) {  
                setRun(text, token[i]);  
            }  
        }  
    }  
    txtQuery.CaretPosition = para.Inlines.First(x => x.Tag != null && x.Tag.Equals(1)).ElementEnd;  
}  

in the setRun function I add these Run in the Paragraph like this;

void setRun(string token, char nextToken) {  
    var para = txtQuery.CaretPosition.Paragraph;  
    var run = new Run(token);  
    if (token.EndsWith('\t')) {  
        run.Text = ((FunKey)FunKeys.CurrentItem).Name;  
        run.Tag = 1;  
    }  
    else {  
        if (!(nextToken.Equals('(') || nextToken.Equals(')')))  
            run.Text += " ";  
    }  
    setNormalStyle(run, getTag(token));  
    para.Inlines.Add(run);  
}  

getTag function gets the tag from another source or sets a constant and returns that. and setNormalStyle styles the Run:

void setNormalStyle(Run run, object tag) {  
    switch (tag) {  
        case "Core Function":  
        case "Aggregate Function":  
        case "Math Function":  
            run.Foreground = functionBrush;  
            run.FontWeight = FontWeights.Bold;  
            break;  
        case "Table":  
        case "Column":  
            run.Foreground = tableColumnBrush;  
            break;  
        case "Keyword":  
            run.Foreground = keyWordBrush;  
            run.FontWeight = FontWeights.Bold;  
            break;  
        default: run.Foreground = defaultBrush; break;  
    }  
}  

In GitHub, I've uploaded the project so that you can test and provide a solution. You can click on the topleft button and select a sqlite database for testing and to get resultset in the rightmost datagrid, hit F5. I've tried this:

if(e.Key == Key.Space) {  
    //var lastToken = txtQuery.CaretPosition.GetTextInRun(LogicalDirection.Backward).Trim();  
    //txtQuery.CaretPosition.DeleteTextInRun(lastToken.Length);  
    //setRun(lastToken, '\0');  
}  

in the onKeyDownOnQuery eventhandler, doesn't work!

I often copy the result set and paste those in excel for further review. If the rightmost DataGrid has a large dataset and I select all (CTRL + a), the app stops responding!

Developer technologies Windows Presentation Foundation
0 comments No comments
{count} votes

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.