With Visual Studio SDK, how would I collapse a section of code? - c#

I can get a selection of text via TextSelection.
And I can highlight specific sections. How would I collapse said section, couldn’t find anything in the documentation for the Visual Studio SDK about collapsing or hiding a section.
Edit 1
The code I want to collapse uses c++ syntax
Edit 2
I am attempting to writing an extension which allows me to collapse code, however I can not seem to find a reference to how to invoke such an option from the visual studio SDK documentation.

IOutliningManager might be what you're looking for.
It provides methods that will allow you to get all collapsible regions, collapsed regions, and methods that allow you to expand or collapse a given region.
As for an example, you might find this useful. Although the OP had issues with their code that weren't resolved via the linked thread, the provided code snippet might get you going in the right direction. I've included the snippet below:
[Microsoft.VisualStudio.Utilities.ContentType("text")]
[Microsoft.VisualStudio.Text.Editor.TextViewRole(Microsoft.VisualStudio.Text.Editor.PredefinedTextViewRoles.Editable)]
[Export(typeof(IVsTextViewCreationListener))]
public class Main : IVsTextViewCreationListener
{
private IOutliningManager _outliningManager;
private IVsEditorAdaptersFactoryService _editorAdaptersFactoryService;
public void VsTextViewCreated(IVsTextView textViewAdapter)
{
IComponentModel componentModel = (IComponentModel)ServiceProvider.GlobalProvider.GetService(typeof(SComponentModel));
if (componentModel != null)
{
IOutliningManagerService outliningManagerService = componentModel.GetService<IOutliningManagerService>();
_editorAdaptersFactoryService = componentModel.GetService<IVsEditorAdaptersFactoryService>();
if (outliningManagerService != null)
{
if (textViewAdapter != null && _editorAdaptersFactoryService != null)
{
var textView = _editorAdaptersFactoryService.GetWpfTextView(textViewAdapter);
var snapshot = textView.TextSnapshot;
var snapshotSpan = new Microsoft.VisualStudio.Text.SnapshotSpan(snapshot, new Microsoft.VisualStudio.Text.Span(0, snapshot.Length));
_outliningManager = outliningManagerService.GetOutliningManager(textView);
var regions = _outliningManager.GetAllRegions(snapshotSpan);
foreach (var reg in regions)
{
_outliningManager.TryCollapse(reg);
}
}
}
}
}
}
Good luck!

Related

Can't use Expand and Collapse methods or patterns on TreeItems using FlaUI in C#?

I'm trying to define a function that expands or collapses a given TreeItem by a target state using FlaUI for testing a program in C#.
I'm able to find the element, but I can't access any information or methods for expanding and collapsing TreeItem elements. I get the following error when trying to set the currentPattern variable. I was also not able to just run the Expand and Collapse methods on the TreeItem.
Error:
FlaUI.Core.Exceptions.PatternNotSupportedException: 'The requested pattern 'ExpandCollapse [#10005]' is not supported'
The function I have written is:
public TreeItem ToggleTreeNode(string inNodeName, ExpandCollapseState inTargetState, AutomationElement inParentNode = null)
{
TreeItem nodeElement = null; //TreeItem nodeElement = null;
if (inParentNode == null)
{
nodeElement = mSTGOCMainForm.FindFirstDescendant(cf => cf.ByName(inNodeName)).AsTreeItem();
}
else
{
nodeElement = inParentNode.FindFirstDescendant(cf => cf.ByName(inNodeName)).AsTreeItem();
}
// Collapse or Expand
var currentPattern = nodeElement.Patterns.ExpandCollapse.Pattern;
var currentState = currentPattern.ExpandCollapseState.Value;
if (inTargetState != currentState)
{
//Then do the operation
if (inTargetState == ExpandCollapseState.Collapsed)
{
nodeElement.Collapse();
}
else if (inTargetState == ExpandCollapseState.Expanded)
{
nodeElement.Expand();
}
}
return nodeElement;
}
I'm using FlaUI.Core and FlaUI.UIA2, version 3.2.0.
It seems that your TreeItems just don't support the UIA Collapse/Expand pattern. Either there is a nested or parent element that supports the pattern (check with any inspect tool) or you need to use keyboard or mouse to collapse/expand.
I had the same error when I found a button on my TreeItem. The button had an automation ID, but the TreeItem did not. To use Expand(), I had to find the button and define my variable as the Parent. Note the .Parent.AsTreeItem() at the end.
TreeItem DiagnosticLogsTreeItem => Window.FindFirstDescendant(By.ByAutomationId("PageLink_Diagnostic Logs")).Parent.AsTreeItem();

XamlBindingHelper Class

Can somebody provide an overview for use of the XamlBindingHelper class with examples? Specifically the GetDataTemplateComponent and SetDataTemplateComponent method.
In the official document, it says
This class is for use in code that is generated by the XAML compiler.
This tells me that I should be able to find some reference of it in code-generated classes (.g.cs) by x:Bind, given there's not a single thread on the Internet that explains what exactly it does.
So I created a test UWP project with a ListView, and inside its ItemTemplate I threw in some x:Bind with x:Phase. After I compiled the project, I found some of its methods used inside my MainPage.g.cs -
XamlBindingHelper.ConvertValue
public static void Set_Windows_UI_Xaml_Controls_ItemsControl_ItemsSource(global::Windows.UI.Xaml.Controls.ItemsControl obj, global::System.Object value, string targetNullValue)
{
if (value == null && targetNullValue != null)
{
value = (global::System.Object) global::Windows.UI.Xaml.Markup.XamlBindingHelper.ConvertValue(typeof(global::System.Object), targetNullValue);
}
obj.ItemsSource = value;
}
Apparently the XamlBindingHelper.ConvertValue method is for converting values. I knew this already, as I used it in one of my recent answers on SO.
XamlBindingHelper.SuspendRendering & XamlBindingHelper.ResumeRendering
public int ProcessBindings(global::Windows.UI.Xaml.Controls.ContainerContentChangingEventArgs args)
{
int nextPhase = -1;
switch(args.Phase)
{
case 0:
nextPhase = 1;
this.SetDataRoot(args.Item);
if (!removedDataContextHandler)
{
removedDataContextHandler = true;
((global::Windows.UI.Xaml.Controls.StackPanel)args.ItemContainer.ContentTemplateRoot).DataContextChanged -= this.DataContextChangedHandler;
}
this.initialized = true;
break;
case 1:
global::Windows.UI.Xaml.Markup.XamlBindingHelper.ResumeRendering(this.obj4);
nextPhase = -1;
break;
}
this.Update_((global::System.String) args.Item, 1 << (int)args.Phase);
return nextPhase;
}
public void ResetTemplate()
{
this.bindingsTracking.ReleaseAllListeners();
global::Windows.UI.Xaml.Markup.XamlBindingHelper.SuspendRendering(this.obj4);
}
XamlBindingHelper.SuspendRendering & XamlBindingHelper.ResumeRendering look very interesting. They seem to be the key functions to enable ListView/GridView's incremental item rendering which helps improve the overall panning/scrolling experience.
So apart from x:DeferLoadingStrategy and x:Load(Creators Update), they are something else that could be used to improve your app performance.
IDataTemplateComponent & IDataTemplateExtension
However, I couldn't find anything related to GetDataTemplateComponent and SetDataTemplateComponent. I even tried to manually set this attached property in XAML but the get method always returned null.
And here's the interesting bit. I later found this piece of code in the generated class.
case 2: // MainPage.xaml line 13
{
global::Windows.UI.Xaml.Controls.Grid element2 = (global::Windows.UI.Xaml.Controls.Grid)target;
MainPage_obj2_Bindings bindings = new MainPage_obj2_Bindings();
returnValue = bindings;
bindings.SetDataRoot(element2.DataContext);
element2.DataContextChanged += bindings.DataContextChangedHandler;
global::Windows.UI.Xaml.DataTemplate.SetExtensionInstance(element2, bindings);
}
break;
The method DataTemplate.SetExtensionInstance looks very similar to XamlBindingHelper.SetDataTemplateComponent. It takes element2 which is the root Grid inside the ItemTemplate of my ListView, and an IDataTemplateExtension; where the latter takes an element and an IDataTemplateComponent. If you have a look at their definitions, their functionalities are very similar, which makes me think if DataTemplate.SetExtensionInstance is the replacement of XamlBindingHelper.SetDataTemplateComponent? I'd love to know if otherwise.
Unlike IDataTemplateComponent, you can get an instance of the IDataTemplateExtension in your code -
var firstItemContainer = (ListViewItem)MyListView.ContainerFromIndex(0);
var rootGrid = (Grid)firstItemContainer?.ContentTemplateRoot;
var dataTemplateEx = DataTemplate.GetExtensionInstance(rootGrid);
In my case, the dataTemplateEx is an instance of another generated class called MainPage_obj2_Bindings, where you have access to methods like ResetTemplate and ProcessBindings.
I assume they could be helpful if you were to build your own custom list controls, but other than that I just can't see why you would ever need them.

Highlighting a particular control while capturing screenshot of a dialog in web page in c#

I have a requirement to capture the screen shot of the opened dialog with a particular html control highlighted ( whose static id is given ). currently I Implemented the code following manner :
public void Snapshot()
{
Image currentImage = null;
currentImage = GetOpenedDialogFrame().CaptureImage();
}
public UITestControl GetOpenedDialogFrame()
{
var dialogsFrames = new HtmlDiv(this.BrowserMainWindow.UiMobiControlDocument);
dialogsFrames.SearchProperties.Add(new PropertyExpression(HtmlControl.PropertyNames.Class, "mcw-dialog", PropertyExpressionOperator.Contains));
var dialogs = dialogsFrames.FindMatchingControls();
if (dialogs.Count == 0)
{
return null;
}
return dialogs[dialogs.Count - 1];
}
Now I have to write the code to highlight the particular html control while taking a screenshot. The DrawHighlight() method of Microsoft.VisualStudio.TestTools.UITesting.dll does not take any parameter so how can I highlight a particular html control in the screenshot.
DrawHighlight() is a method of a UI Control. It could be used in this style:
public void Snapshot()
{
Image currentImage = null;
var control = GetOpenedDialogFrame();
// TODO: protect the code below against control==null.
control.DrawHighlight();
currentImage = control.CaptureImage();
}
Whilst that answers your question about DrawHighlight, I am not sure it will achieve what you want. Please see this question the Microsoft forums where they are trying to do a similar screen capture.
Why not simply user the playback settings:
Playback.PlaybackSettings.LoggerOverrideState = HtmlLoggerState.AllActionSnapshot;
This will produce the html log file with all the screenshots that your codedui test went threw.
After searching for the matching controls you can try to highlight each one of them.
something like:
foreach( var control in controls)
{
control.drawhighlight();
}
that way you'll be able to which controls are located by the playback(qtagent to be more precise). furthermore this will help you decide which instance to refer to. (run and wait to see which controls are highlighted, pick the one you need and hard code it to be part of the test).
so after the test run you'll end up with something like:
var dialogs = dialogsFrames.FindMatchingControls();
dialogs[desiredLocation].drawhighlight();
hope this helps.

Highlight Goto in Visual Studio 2010

I am currently translating old generated C# code which is full of goto. Please dont comment on that, I know its horrible.
Anyway, is there a way / extension / whatever to make goto-statements more readable? Its a pain to find the place where the code jumps to. I dont want to use the search-function since it makes me lose my orientation.
All I found is this:
http://visualstudiogallery.msdn.microsoft.com/4b286b9c-4dd5-416b-b143-e31d36dc622b
and it doesnt work.
Can you recommend anything?
A bit late maybe, but you can build your own using Visual Studio Extensibility (and therefore add custom behavior as well): Inside the Editor: Tags and Classifier. The steps are:
1) Create an Editor Classifier project (builtin project type)
2) Delete the existing class files
3) Add the code below. It will colorize all 'goto' statements in code portions in red:
internal class GotoTagger : ITagger<GotoTag>
{
private ITextSearchService _textSearchService;
private ITextStructureNavigator _textStructureNavigator;
event EventHandler<SnapshotSpanEventArgs> ITagger<GotoTag>.TagsChanged { add { } remove { } }
public GotoTagger(ITextSearchService textSearchService, ITextStructureNavigator textStructureNavigator)
{
_textSearchService = textSearchService;
_textStructureNavigator = textStructureNavigator;
}
public IEnumerable<ITagSpan<GotoTag>> GetTags(NormalizedSnapshotSpanCollection spans)
{
if (spans.Count == 0)
yield break;
if (spans.Count > 0)
{
// look for 'goto' occurrences
foreach (SnapshotSpan span in _textSearchService.FindAll(new FindData("goto", spans[0].Snapshot, FindOptions.WholeWord | FindOptions.MatchCase, _textStructureNavigator)))
{
yield return new TagSpan<GotoTag>(span, new GotoTag());
}
}
}
}
[Export(typeof(IViewTaggerProvider))]
[TagType(typeof(TextMarkerTag))]
[ContentType("code")] // only for code portion. Could be changed to csharp to colorize only C# code for example
internal class GotoTaggerProvider : IViewTaggerProvider
{
[Import]
internal ITextSearchService TextSearchService { get; set; }
[Import]
internal ITextStructureNavigatorSelectorService TextStructureNavigatorSelector { get; set; }
public ITagger<T> CreateTagger<T>(ITextView textView, ITextBuffer buffer) where T : ITag
{
if (textView.TextBuffer != buffer)
return null;
return new GotoTagger(TextSearchService, TextStructureNavigatorSelector.GetTextStructureNavigator(buffer)) as ITagger<T>;
}
}
internal class GotoTag : TextMarkerTag
{
public GotoTag() : base("goto") { }
}
[Export(typeof(EditorFormatDefinition))]
[Name("goto")]
[UserVisible(true)]
internal class GotoFormatDefinition : MarkerFormatDefinition
{
public GotoFormatDefinition()
{
BackgroundColor = Colors.Red;
ForegroundColor = Colors.White;
DisplayName = "Goto Word";
ZOrder = 5;
}
}
You can consider DevExpress CodeRush. goto statements will get an arrow like this: . Hovering over the arrow highlights the statement following the label (if it's already visible), and clicking it makes it visible and moves the cursor to that statement.
Try ReSharper's Navigate to function exits.
Or Coderush's flow break icons
Also note, that you can use "Ctrl" + "-" to jump back to the last place in the code, you were looking at.
This is probably very obvious, but it seemed to me like CSharpie might be unaware of this hotkey.

Alternative to OverLibWrapper for displaying control tooltips in ASP.NET

I looked into a nice way to display tooltips dynamically and I found OverLibWrapper, which was exactly what I needed.
I have all the tooltip data stored in a custom configuration section, the tooltips are bound to their respective controls during Page_Load.
I did a quick test and worked fine. The problem came up when I realized that OverLibWrapper didn't work on masterpages. Our website has uses quite a few masterpages, so taking them out isn't an option.
I was wondering if there's anything like OverLibWrapper that I could use.
EDIT:
What I'm looking for is a control to display good-looking tooltips on mouseover preferably instantly like overlib (nothing fancy because I'm just displaying raw text) in a dynamic way, because the tooltip property in ASP.NET is not very pretty and takes a while to appear. For example let's say I have a collection of Messages:
class Message
{
string ctrlid, msgtodisplay;
}
And when the page is loaded:
TooltipManager manager;
foreach(var m in messages)
{
Tooltip tltp=new Tooltip;
m.ControlID=m.ctrlid;
m.Message=m.msgtodisplay;
manager.AddTooltip(tltp);
}
So basically something that offers the functionality of Tooltip and TooltipManager.
Take a look at this:
NotesTooltip
I think this will do what you need.
Have you thought about just writing your own? Sometimes I find the things out there by other people are never quite fit for my needs.
Well I finally solved my problem:
I've used this function to find any control (works with masterpages):
public static Control FindControlRecursive(Control root, string id)
{
if (id == string.Empty)
return null;
if (root.ID == id)
return root;
foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
return t;
}
return null;
}
And this method:
public static void load(Page page, string pageFileName)
{
foreach (ConfiguracionElem elem in Configuracion.GetConfig(pageFileName).Tooltips)
{
WebControl ctrl = (WebControl)FindControlRecursive(page, elem.controlid);
if (ctrl == null)
throw new ControlNotFoundException("There's no control'"+elem.controlid+"'")
else
{
ctrl.Attributes.Add("onmouseover","return overlib('"+elem.message+"');");
ctrl.Attributes.Add("onmouseout","return nd();");
}
}
}
I added the Overlib library manually to a script folder, then I iterated through my Custom Configuration Section (where my tooltip data is stored) to add the javascript attributes dynamically.

Categories