Duplicate of first entry in navigation bar in custom Visual Studio Language Service - visual-studio

I'm implementing a Visual Studio Language Service for a custom scripting language used internally at my company, and I've run into an issue with the navigation bar implemented as a subclass of TypeAndMemberDropdownBars. The subclass is created by my LanguageService subclass' LanguageService.CreateDropDownHelper method.
In the OnSynchronizeDropdowns method I'm iterating through the types defined in the file and adding DropDownMembers to the passed-in array to fill out the navigation bar. The issue I'm seeing is that the first item in the array is being duplicated and placed at the end of the listing by code that I don't have access to. This extra item does not behave correctly when selected (nothing happens), but doesn't seem to cause any other issues; the rest of the items in the list work fine. Additionally, this only seems to happen for the type dropdown box - the members dropdown box does not display this behavior.
I'm hoping someone else has seen and resolved this issue and could provide some assistance. Thanks!

Turns out this was caused by me calling LanguageService.SynchronizeDropdowns from my LanguageService.ParseSource method, which was being called on a background thread. I've fixed the problem by setting a flag when ParseSource does a Check parse, and then implementing a check for that flag in my LanguageService.OnIdle function that will call SynchronizeDropdowns. It's now working as expected!

A better solution is to implement the LanguageService.OnParseComplete callback, and call SynchronizeDropdowns from there. OnParseComplete is always called from the main thread, so this prevents any synchronization issues from coming up, and also keeps you from having to keep track of whether or not you need to call SynchronizeDropdowns().

Related

How to intercept the changes to this properties window?

I'm trying to intercept the change events triggered (any field) when this property window is changed in a VS Extension project (vsix). This extension will target VS versions upto 2019 (the latest one).
I've used dte.Events.TextEditorEvents.LineChanged but it captures the event intermittently.
Is there a specific event that I can look at for this purpose?
Initially I mistakenly thought IVsRunningDocTableEvents.OnAfterAttributeChange could be used. But after reviewing the designer code base (one of the few I've seen written in VB.NET), I found that this particular designer sets the windowframe's dirty by explicitly invoking IVsWindowFrame.SetProperty with VSFPROPID_OverrideDirtyState, which per the comments in the vsshell80.idl file:
VSFPROPID_OverrideDirtyState = -4014, // BOOL/EMPTY -- tri-state value to control dirty star (*) in window caption
// VT_EMPTY: default handling of dirty star
// VARIANT_TRUE: override default handling to SHOW dirty star
// VARIANT_FALSE: override default handling to show NO dirty star
indicates this designer doesn't leverage the default mechanism driven by the RDT. :-(
The only notification I could find that you could possibly intercept would be an IPropertyNotifyChange on the individual properties themselves, which does fire, as soon as you change a given setting and move focus to another control.
This may not be what you're looking for, but if you can explain why you need such a notification, I may be able to come up with something better than periodically polling the designers VSFPROPID_OverrideDirtyState property (which is the only other thing that immediately comes to mind).
Thanks,
Ed....

How can I know who calls the method in Xcode?

Does Xcode have a way to show the caller function of a method? I want to know all of the calling functions of a method in a class. A solution would be to find the method in the project, but sometimes different classes have methods with the same name - That could find us a method we're not looking for..
Many other IDEs have this capability, such as Visual C++ 2003/2005/2008,Eclipse ...
Can you do this in XCode?
Xcode 4.4 intrudced this functionality:
New Features in Xcode 4.4 (Scroll down to 'Find and Search Additions')
Move your cursor on top of the function you are interested in
Open the Assistant editor(⌃ +⌘+Enter)
On the top of the assistant editor, Select 'Callers'
You will see a list of all the function that's calling your function
Not the as effective as other IDEs, but does the job.
Yes. Set a breakpoint inside your method, then when it breaks, there are two spots to see a stack. First is in Xcode's "console" area (usually the bottom middle), there is a top-bar which may not immediately appear to be navigable, but it is a select-style UI control which has the entire stack in it. Selecting a different level shows you that scope's variables, etc. and pops your editor to that exact file (where you can mouse-over variables to see their in-memory real-time values). Second is in the left-hand area (where you normally browse files). There is another tab there (besides the file browser) for exactly this purpose. There is a slider at the bottom which controls how many "steps" in the stack you see; clicking on one has a similar affect.
For simple refactoring such as method re-naming, you can use the contextual-menu when you right-click a selected method-name, and Xcode will replace all identical selectors in your project. However, this does not address what you mentioned about different classes having methods with the same signature. It does, however, give you a very nice interface for reviewing the changes in-context and easily accepting or rejecting them one at a time.
It might be noted, however, that changing method signatures often may be a sign of poor design, and particularly if you have to do it with methods which have the same signature on different classes (which are not "siblings" and therefore should both get the rename)

Selectively displaying Installerpane of an installerplugin at runtime

I have written an installerplugin to show a custom pane in the pkg installer. I want to display the pane only during first install and hide it when upgrading. I know how to find out if the package has already been installed or not but I am not able to figure out the logic of showing/hiding the installerpane based on a runtime decision.
One method I could think of is that the installerplugin contains an Installersection outlet called parentSection. And installersection class has a function shouldload whose return value decides whether the section should be loaded or not. And this article mentions that the installersection methods can be overloaded. But I am unable to think of a way to overload the functions as parentSection is just an object inside the installerpane class.
Even though it's been several months since sanmukh asked this question, I figured I would post the answer since I figured out how to do this.
The solution is indeed to subclass InstallerSection and override the shouldLoad method. To use it, you have to edit your plug-in's Info.plist file and change the entry for "NSPrincipalClass" (or "Principal Class" as it appears in Xcode 4) to be your new InstallerSection derived class. Afterwards when your package loads, the new shouldLoad method will be called, allowing you to programmatically decide whether the installer pane should be visible.

How can I trace what happens during XAML loading?

I would like to find a way to see what happens while my XAML is being loaded. What classes are being instantiated, and in what order? Which properties are being set, to what values, and in what order? Which methods are being called (e.g. BeginInit, EndInit, etc.), in what order, and with what parameters? That sort of thing.
(If anyone's curious as to why, it's because the XAML loader is doing something magic that I can't duplicate in code, and I'm trying to figure out what it is.)
My first idea: Configure VS to debug into the .NET source code, and single-step through the XAML-loading code to see what happens. Unfortunately, source stepping has been busted for months, and there's no sign of that changing.
My second idea: Make my own classes that descend from WPF classes, override OnPropertyChanged, and do a Debug.WriteLine. Unfortunately, one of the classes I want to know about (BitmapImage) is sealed, so I can't descend from it.
Anyone have other ideas on how I could get some visibility into what the XAML loader is doing? Are there any tools (profiler, maybe?) that could give me a call graph? Is there a way to turn on some kind of logging in the XAML loader? Thoughts / suggestions?
Edit: The article Steve linked to does have the answer, though their sample code makes every event get displayed twice. For reference, here's how to make this work in code (no app.config changes required). Add these lines before the InitializeComponent() call (or type both lines into the Immediate window in the debugger):
PresentationTraceSources.Refresh();
PresentationTraceSources.MarkupSource.Switch.Level = SourceLevels.All;
This will cause detailed output to show up in VS's Output window, including the properties that get set magically behind the scenes.
You can trace a lot of the binding and loading with system.diagnostics. I've found a number of problems using this namespace. Its unwieldy like everything else in WPF, but it works. You can see what's getting set and where.

Distinguish between designer and runtime code

I have two processes which exange messages each other.
Process A is a normal (i.e non-qt) program which sends messages to process B.
Process B is a QT GUI application showing received messages into a text box.
I created a customized widget (called ShowMessages) which inherits from QPlainTextEdit and reads messages from a pipe when a timer expires, and appends them in the text box.
Code is not really designed like this (which would be pretty bad design I think), but it's just to make things simple here.
For reasons I won't tell, process A cannot be shut down while I'm creating the form using qt-designer.
Problem is that while I'm using qt designer (thus selecting the ShowMessages widget and putting it within the window) the widget begins to show messages, even if I'm in the designer. This feature is cool but the problem is that when I save the form, already present messages are saved in .ui file, which results in turn in bad behaviour when I start process B (because process starts showing messages I received during the creation phase).
I could clean the text box just after process B starts, but I think that avoiding messages to be present in the .ui file is much better. What I want is to be able to write code like this for the widget:
if <I'm not in the designer>
timer = QtCore.QTimer(self)
QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self, QtCore.SLOT("on_timer()"));
timer.start(2000)
Is there an qt function to know if I'm in the designer? Do you think that distinguishing between designer and runtime code is "bad"?
(Sorry for mistakes, but English is not my primary language)
Maybe your widget should have a flag for whether it's "active" and default it to False so while you're in the designer, it doesn't do anything at all. In code you would set it to active when you want to see the messages. Then you also have the ability to turn it off in other scenarios as well.
But I have to say, it sounds like you're putting "controller" code into a "view" widget which can and probably will spell trouble for you down the road (including the current Qt designer problem you're having now).
Consider reading up on the MVC (model-view-controller) design pattern, if you haven't already.
Update:
To be fair, your question did ask how to detect whether you're in designer :)
http://doc.trolltech.com/4.3/designer-creating-custom-widgets.html#creating-well-behaved-widgets
To give custom widgets special
behavior in Qt Designer, provide an
implementation of the initialize()
function to configure the widget
construction process for Qt Designer
specific behavior. This function will
be called for the first time before
any calls to createWidget() and could
perhaps set an internal flag that can
be tested later when Qt Designer calls
the plugin's createWidget() function.
According to the doc, you basically could set your "inDesignerFlag" to true in the initialize() function of your widget. Then detect that flag where required in your widget's code.

Resources