Code Outlining - Ranged Based

SyntaxEditor for WPF Forum

Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Version: 10.1.0523
Avatar


Hi I have a question regarding code outlining. I had been using token based outlining source in my code and I had it working pretty much how I wanted other than I was having a little difficulty setting the text that I wanted to be displayed when a region was collapsed, however, the more I read about using regions and the fact that our users will be opening very large files from time to time I believe that the range based approach would yield better performance overall so I re-factored my code using your code outlining ranged based example.

Everything is working correctly in regards to the applicable text collapsing but I am again faced with the issue of not being able to set the text I want displayed when a region is collapsed. For example when a function is collapsed I want the function header displayed just like your example but as it is now nothing displays other than the default [...] I have checked and double checked my code with your example and I see nothing wrong or missing. I have tried to implement an over-ride of GetCollapsedContent in a new class and hook that up to my code but with no luck so I must be doing something wrong?


Thanks,
Mick George

Comments (11)

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Mick,

So basically it sounds like you are already combining the concepts from our "CodeOutliningCollapsedText" and "CodeOutliningRangeBased" QuickStarts, which is what I would suggest.

If you have a custom OutliningNodeDefinition in which you override GetCollapsedContent like we do in the "CodeOutliningCollapsedText" QuickStart then it should be working. Maybe put a breakpoint in there to see if it's getting called.

If not, check your IOutliningSource implementation code to ensure you are actually creating nodes that use that custom node definition class.


Actipro Software Support

Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Avatar
Thank you for the quick response.

I do believe I am missing something. Currently I am using your code from CodeOutliningRangeBased and this example does not implement an over-ride for GetCollapsedContent yet the text displayed with collapsed text is not the same as mine, i.e I only see [...] but your example displays the function header. So I then tried to implement GetCollapsedContent but I run into problems with using more than one base class, I am a little lost at the moment.
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
The OutliningNodeDefinition you use tells SyntaxEditor what text to display when a node using that definition is collapsed. If the node should always have fixed text other than "...", you can set it like:
multiLineCommentDefinition.DefaultCollapsedContent = "/**/";
If you want to allow the text to be constructed dynamically then you need to make a class that inherits OutliningNodeDefinition, overrides its GetCollapsedContent method like in the "CodeOutliningCollapsedText" QuickStart, and use that instead.


Actipro Software Support

Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Avatar
Quote:

If you want to allow the text to be constructed dynamically then you need to make a class that inherits OutliningNodeDefinition, overrides its GetCollapsedContent method like in the "CodeOutliningCollapsedText" QuickStart, and use that instead.


I also tried this method, I created a new class called PostOutliningNodeDefinition and inherited from OutliningNodeDefinition I then inherited this new class in my PostOutliner class as shown below:

public class PostOutliner : PostOutliningNodeDefinition, IOutliner
    {
    }
I placed break points in my PostOutliningNodeDefinition and code reached the constructor but when I collapsed a region the GetCollapsedContent method was never reached.

public class PostOutliningNodeDefinition : OutliningNodeDefinition
    {
        public PostOutliningNodeDefinition()
            : base("PostOutliningNodeDefinition")
        {

        }

        /// <summary>
        /// Returns the content that should be displayed when the outlining node is collapsed.
        /// </summary>
        /// <param name="node">The <see cref="IOutliningNode"/>, based on this definition, for which content is requested.</param>
        /// <returns>The content that should be displayed when the outlining node is collapsed.</returns>
        /// <remarks>
        /// Only string-based content is currently supported.
        /// The default implementation of this method returns the value of the <see cref="DefaultCollapsedContent"/> property.
        /// This method can be overridden to generate unique collapsed content for a particular node.
        /// </remarks>
        public override object GetCollapsedContent(IOutliningNode node)
        {
            // Get the node's snapshot range
            TextSnapshotRange snapshotRange = node.SnapshotRange;

            // If the comment is over multiple lines...
            if (snapshotRange.StartPosition.Line < snapshotRange.EndPosition.Line)
            {
                // Use the text in the first line
                int lineEndOffset = snapshotRange.StartLine.EndOffset;
                return snapshotRange.Snapshot.GetSubstring(new TextRange(snapshotRange.StartOffset, lineEndOffset)) + "...";
            }
            else
            {
                // On a single line... use default collapsed content
                return this.DefaultCollapsedContent;
            }
        }

    }
I'm sure it is something simple I am over looking I am just having a hard time putting my finger on it, I do appreciate your patience in assisting me with my problem.
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
OutliningNodeDefinition objects are used by your IOutliningSource implementation. IOutliners just provide an IOutliningSource for a text snapshot.

So you have things a bit circular here:
PostOutliner : PostOutliningNodeDefinition, IOutliner

PostOutliner should not be inheriting PostOutliningNodeDefinition. PostOutliner should just implement IOutliner.

Then whatever IOutliningSource you make that you return from your IOutliner, that IOutliningSource should be using an PostOutliningNodeDefinition instance when it calls this.AddNode, etc. You can look in our samples to see how that is done.


Actipro Software Support

Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Avatar
I assumed I was doing something wrong with inheriting PostOutliningNodeDefinition but I was just grasping at straws at that point.

Perhaps I am not being clear enough with my explanation and please correct me if I am wrong.

I originally implemented code outlining based on your CodeOutliningCollapsedText example that is token based. I was able to get this code to function as expected including the GetCollapsedContent, however, the text displayed from collapsed text was not entirely correct and I was working on fine tuning it. It was at this time I read in your help file that a range based outliner would be more suited for large files and because our customers will be using very large files I decided to re-factor my code based on your CodeOutliningRangeBased example.

Interestingly enough this example does not implement GetCollapsedContent but the text displayed from collapsed text was exactly how I wanted my text to be displayed but once I had implemented your code I do not get any text displayed when collapsing text other than "[...]" which lead me here to ask if I should somehow add an implementation of GetCollapsedContent, does that make sense?

I am a little frustrated at this point and am thinking of just going back to the token based solution but I than I have to worry about large file performance.
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Mick,

Maybe it would be best if you just made a quick ZIPped simple project that shows the issue and email it to us with a renamed file extension so we can take a look. It's probably something really simple that you're doing wrong since as long as you are using custom OutliningNodeDefinitions with GetCollapsedContent overrides properly, it shouldn't matter if you use a token- or range-based approach.


Actipro Software Support

Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Avatar
Your range based example, unlike your token example, does not implement GetCollapsedContent therefore neither does mine.

I'll see if I can put something together, thanks.
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Right, that's why I originally was suggesting combining the concepts from our "CodeOutliningCollapsedText" and "CodeOutliningRangeBased" QuickStarts.


Actipro Software Support

Posted 9 years ago by Mick George - Software Engineer, CNC Software, Inc.
Avatar
Thanks for all your help but I am just going to admit defeat and roll back to my token based code. If at a later date large files do become a problem I'll revisit this.
Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Ok, if you change your mind just send us a simple sample project that shows the issue and we'll help.


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.