locked
How can I force an IWpfTextView to refresh/invalidate it's layout? RRS feed

  • Question

  • In my extension(MEF) I want to set tab offsets for every line programitically.

    I need to set not only the first tab offset but also the other tab offsets too in the line, so I created TextFormattingParagraphProperties  and do calculation of tab offsets in create methods and return appropriate values. This works untill I want to refresh tab offsets of other lines, expect the line one is changing. Seems VS call ITextParagraphPropertiesFactoryService.Create method only for the edited line.

    Is there any way to force the other lines refresh too? 

    One way I found is to create a classifier and fire event each time tabs changed, but this works only for VS2010. Are there any reason why refreshing classifer doesn't call ITextParagraphPropertiesFactoryService.Create  on VS2012 and call on VS2010? 

    Thanks in advance

    Arsen

    Thursday, November 8, 2012 10:10 PM

All replies

  • Hi Arsen,

    Thank you for posting in the MSDN Forum.
     
    I will involve some experts into this issue to see whether they can help you out. There might be some time delay, appreciate for your patience.
     
    Thank you for your understanding and support.
     
    Best regards,


    Ego [MSFT]
    MSDN Community Support | Feedback to us

    Monday, November 12, 2012 7:32 AM
  • Thanks Ego,

    I really approciate your help, I lost a lot of time waste and seems no way to solve this without vs experts help. here is simular question given by someone else that also stay without answer, please refer if my question is not clear enough. 

    Going forward for some help

    Thanks in advance,

    Arsen

    Monday, November 12, 2012 9:42 PM
  • Hi Arsen,

    I don't believe so. Based on what Ameen mentioned in previous conversations/posts, there isn't any way to directly refresh the layout.

    As to why you are not seeing the ITextParagraphPropertiesFactoryService.Create being invoked after porting to VS 2012, I cannot say. I would likely need to debug a repro of the behavior. Can you confirm that the extension is properly registered and is loading into the 2012 IDE?

    If your need is urgent, please consider opening an official support incident with Microsoft. Details and options for opening a support incident with Microsoft Technical Support can be found at the end of this VSX blog entry.

    Sincerely,


    Ed Dore

    Wednesday, November 14, 2012 8:31 PM
  • Hi Ed,

    Thanks for response,

    with the help of Ameen I found a way to do that last time, that was to call ClassificationChanged event and it force tabs to refresh, but in vs2012 it doesn't

    Yes I am sure that it loads on vs2012, I even create extension from scratch under vs2012 templates, and it have the same behavior, I success to debug so the extension was loaded

    I will create a sample and upload to skydrive that shows this difference

    Thanks,

    Arsen

    Wednesday, November 14, 2012 11:46 PM
  • Thanks Arsen,

    Feel free to ping me via email with the repro (email is in my MSDN profile page), and I'll fire it up and see if we can figure out the problem.

    Ed...


    Ed Dore

    Thursday, November 15, 2012 10:23 PM
  • Hi Ed,

    I sent samples by mails, please have a look when you would find a time

    Thanks a lot,

    Arsen

    Friday, November 16, 2012 6:04 PM
  • Are there any recomendetions on this question please? I am working on this few weeks and can't get things done, here  is sample I created that shows the difference(uploaded in skydrive) if someone would like to take a look also. please don't forget to put Keep Tabs from settings 

    try to enter

    1<TAB>2<TAB>3

    4<TAB>5<TAB>6

    than add symbols near to 1

    111111<TAB>2<TAB>3

    4<TAB>5<TAB>6

    You will see the difference


    Wednesday, November 28, 2012 8:03 PM
  • Hi Arsen,

    I think we worked on this through a paid case, so I am closing this thread. After discussing with the Products Team we confirmed that, In VS2012 there are improvements related to this behaviour. In VS2012, the IDE actually checks to see if the classification changes event resulted in actually changing the classifications. If the text properties of the line do not change, IDE does reformat the line. Below code would help you to achieve the intended purpose.

     

    [Export(typeof(IWpfTextViewCreationListener))]

        [ContentType("code")]

        [TextViewRole(PredefinedTextViewRoles.Document)]

        internal sealed class CreationListener : IWpfTextViewCreationListener

        {

            public void TextViewCreated(IWpfTextView textView)

            {

                new Listener(textView);

            }

        }

        class Listener

        {

            ITextView _textView;

            ITextDataModel _dataModel;

            public Listener(ITextView textView)

            {

                _textView = textView;

                _dataModel = _textView.TextViewModel.DataModel;

                _textView.Closed += this.OnClosed;

                _dataModel.ContentTypeChanged += this.OnContentTypeChanged;

                //TODO consider using textView.TextBuffer.ChangedHighPriority (which means it will be processed before the view's layout

                //and, as a result, the OnBufferChanged handler below won't force a second layout ... it will just make the normal layout

                //format more text).

                textView.TextBuffer.PostChanged += this.OnBufferChanged;

            }

            void OnContentTypeChanged(object sender, TextDataModelContentTypeChangedEventArgs e)

            {

                if (!e.AfterContentType.IsOfType("code"))

                {

                    //We are no longer a "code" content type so unhook all the events so we can be garbage collected.

                    this.OnClosed(nullnull);

                }

            }

            private void OnBufferChanged(object sender, EventArgs e)

            {

                //Force the entire view to reformat.

                //TODO only do this if a line containing tabs was modified.

                int oldTabSize = _textView.Options.GetOptionValue(DefaultOptions.TabSizeOptionId);

                _textView.Options.SetOptionValue(DefaultOptions.TabSizeOptionId, oldTabSize + 1);

                _textView.Options.SetOptionValue(DefaultOptions.TabSizeOptionId, oldTabSize);

            }

            private void OnClosed(object sender, EventArgs e)

            {

                _textView.Closed -= this.OnClosed;

                _textView.TextBuffer.PostChanged -= this.OnBufferChanged;

                _dataModel.ContentTypeChanged -= this.OnContentTypeChanged;

            }

        }

    Also above code has some Caveats: This doesn’t provide very fine-grained control: every line in the view will be reformatted. You can get better control by using the SpaceNegotiatingAdornment tagger and just – at the beginning of each line you want to force a format – create a 0 width adornment. It won’t affect the visual appearance of the line but lines that have a SpaceNegotiatingAdornmentTag bypass the optimization we added in VS2012.

    Thanks,

    Gaurav

    Wednesday, February 6, 2013 11:19 PM
  • I know I should make a new post ( and I will ). I couldn't find any information on ChangeContentType except when I googled it and found this post. 

    It appears to me that there may be a way to change the context within text such as when typing in a <script type='text/javascript'></script> block in a cshtml file. When a look into the textbuffer I see a ContentType.

    My desire is to gain control over the format of the content within a textbuffer and set it to whatever I would like. 



    • Edited by jwize1 Tuesday, June 11, 2013 6:54 AM
    Tuesday, June 11, 2013 6:53 AM