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.
Related
I'm using an imagelist with about 100 different icons to be used in a listview in a C# project using Winforms
The images are referred to by the listview by their index.
Now there has been a graphical overhaul, and all of the icons need to be replaced.
What I did so far was open up the imagelist in the Visual Studio editor, delete image x with index 5, and then add a new version of image x.
The problem with approach is that when deleting image x, all other images with an index higher than 5 are shifted.
And after adding the new version of the icon, I have to click the UP arrow about 95 times to get my new version at index 5 again.
Does anyone know a less painful, and less error prone method to achieve the same result?
Editing the .designer.cs file doesn't really help as it only lists the names of the icons and their index
//
// NavigatorImageList
//
this.NavigatorImageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("NavigatorImageList.ImageStream")));
this.NavigatorImageList.TransparentColor = System.Drawing.Color.Transparent;
this.NavigatorImageList.Images.SetKeyName(0, "dummy.png");
this.NavigatorImageList.Images.SetKeyName(1, "Attribute.png");
this.NavigatorImageList.Images.SetKeyName(2, "Operation.png");
this.NavigatorImageList.Images.SetKeyName(3, "Element.png");
this.NavigatorImageList.Images.SetKeyName(4, "Diagram.png");
this.NavigatorImageList.Images.SetKeyName(5, "Package_element.png");
// ...continues like this for all items ....
The actual images are stored in the .resx file, but they are in a binary format, so also not really an option to edit them there
<data name="NavigatorImageList.ImageStream" mimetype="application/x-microsoft.net.object.binary.base64">
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAB2
1gAAAk1TRnQBSQFMAgEBYwEAAYgBAgGIAQIBEAEAARABAAT/AREBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABkAEBAgABAQEAARAGAAHIJgABeAEtAfABHAHwARwB8AEcAfABHAHwARwWAAG4ATUBMAElATABJQEw
... and many many more lines like this...
I know referring to the images by their index might have been a mistake, but it's a bit late in the game to change that now
TL;DR
I'm looking for an easy way to replace the images in my imagelist without having to change my existing working code that relies on the image indexes.
The Image List Editor has an Image property as well which is not browsable by default. As an option you can make that property visible and then you can easily replace the image at design time without any problem.
Look at the following picture and see Image property:
Here is My Image Collection Editor. It's basically the code of the original Image Collection editor with a small change, finding the collection editor's PropertyGrid and resetting its BrowsableAttributes property.
public class MyImageListEditor : CollectionEditor
{
Type ImageListImageType;
public MyImageListEditor(Type type) : base(type)
{
ImageListImageType = typeof(ControlDesigner).Assembly
.GetType("System.Windows.Forms.Design.ImageListImage");
}
protected override string GetDisplayText(object value)
{
if (value == null)
return string.Empty;
PropertyDescriptor property = TypeDescriptor.GetProperties(value)["Name"];
if (property != null)
{
string str = (string)property.GetValue(value);
if (str != null && str.Length > 0)
return str;
}
if (value.GetType() == ImageListImageType)
value = (object)((dynamic)value).Image;
string name = TypeDescriptor.GetConverter(value).ConvertToString(value);
if (name == null || name.Length == 0)
name = value.GetType().Name;
return name;
}
protected override object CreateInstance(Type type)
{
return ((UITypeEditor)TypeDescriptor.GetEditor(ImageListImageType,
typeof(UITypeEditor))).EditValue(Context, null);
}
protected override CollectionEditor.CollectionForm CreateCollectionForm()
{
CollectionEditor.CollectionForm collectionForm = base.CreateCollectionForm();
collectionForm.Text = "My Image Collection Editor";
var overArchingTableLayoutPanel =
(TableLayoutPanel)collectionForm.Controls["overArchingTableLayoutPanel"];
var propertyBrowser =
(PropertyGrid)overArchingTableLayoutPanel.Controls["propertyBrowser"];
propertyBrowser.BrowsableAttributes = new AttributeCollection();
return collectionForm;
}
protected override IList GetObjectsFromInstance(object instance)
{
return (IList)(instance as ArrayList) ?? (IList)null;
}
}
To register this editor for image list, the easiest solution is registering it inside the constructor of the base class:
public partial class Form1 : MyBaseForm
{
public Form1()
{
InitializeComponent();
}
}
public class MyBaseForm : Form
{
public MyBaseForm()
{
TypeDescriptor.AddAttributes(typeof(ImageList.ImageCollection),
new Attribute[] {
new EditorAttribute(typeof(MyImageListEditor), typeof(UITypeEditor)) });
}
}
Then just close all designers, rebuild solution, close and reopen VS.
That's all!
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!
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.
I have a table which has multiple rows. I want to verify that a specific string StringName is in the table. I used CodedUI to find the control, and the UI map is like this:
public class UIItemTable : WpfTable
{
#region Fields
private UIItemRow mUIItemRow;
#endregion
}
public class UIItemRow : WpfRow
{
#region Fields
private UIBlahBlahBlahCell mUIBlahBlahBlahCell;
#endregion
}
public class UIBlahBlahBlahCell : WpfCell
{
#region Fields
private WpfText mUIBlahBlahBlahText;
#endregion
}
I want to find a WpfText that matches my StringName. So I added a function to UIItemTable:
public class UIItemTable : WpfTable
{
public WpfText Find(string StringName)
{
WpfText StringNameWpfText = new WpfText(this);
StringNameWpfText.SearchProperties[WpfText.PropertyNames.Name] = StringName;
return StringNameWpfText;
}
#region Fields
private UIItemRow mUIItemRow;
#endregion
}
But CodedUI cannot find the WpfText control. The error I received is:
Microsoft.VisualStudio.TestTools.UITest.Extension.UITestControlNotFoundException.
The playback failed to find the control with the given search
properties. Additional Details: TechnologyName: 'UIA' ControlType:
'Text' Name: ...
I think this error may be due to the fact that the WpfCell I want to search is actually a grandchild of the table. But I thought CodedUI handles tree traversals right? How do I search for a grandchild?
You should move your code out of the partial UIMap.designer.cs class as it will be overwritten the next time you record a control/assert/etc. Move you code to the uimap.cs partial class instead.
The text control may or may not be the next level down, if it is not on the child level of UIItemTable, your code will fail. You should try to use the test tool builder cross hair to identify the level it exists at.
You can use the child enumerator and search through all child/grandchild/etc elements until you find your text item, an example below would be something like:
public UIControl FindText(UIControl ui)
{
UIControl returnControl = null;
IEnumerator<UITestControl> UIItemTableChildEnumerator =
ui.GetChildren().GetEnumerator();
while(uiChildEnumerator.MoveNext())
{
if(uiChildEnumerator.Current.DisplayText.equals(StringName))
{
returnControl = uiChildEnumerator.Current
break;
}
else
{
returnControl = this.FindText(uiChildEnumerator.Current)
if(returnControl != null)
{
break;
}
}
}
return returnControl;
}
4 . Another option would be to use the FindMatchingControls() function and parse through similar to the above statement. You might still need the proper direct parents though
WpfText StringNameWpfText = new WpfText(this);
IEnumerator<UITestControl> textItems = StringNameWpfText .FindMatchingControls().GetEnumerator();
while (textItems.MoveNext())
{
//search
}
Hope this helps
I usually find cells first. I believe any content in a table would be in a cell. So we can search for the cells first and then dive in it.
One way to find cell whose value matches with the given string.
WpfCell cell = myWpfTable.FindFirstCellWithValue(string StringName);
if(cell != null)
return cell.Value // returns WpfControl;
else
return null;
Another way to get the value of cell which contains a particular string
WpfCell myCell = myWpfTable.Cells
.FirstOrDefault(c => c.Value.Contains("StringName"));
var myTextControl = myCell != null ? myCell.Value : null;
If the text is nested deep in the cell, then you can do this. Just like what you were doing with the table
// Find cell which contains the particular string, let say it "myCell"
WpfText mytext = new WpfText(myCell);
mytext.SearchProperties.Add(WpfText.PropertyNames.Name, "StringName", PropertyExpressionOperator.Contains);
if(mytext.Exist)
return myText;
else
retrun null;
How can I extend a Button?
I want a Button that has an additional property IsSwitchOffable.
Do I have to write an extra custom control?
EDIT:
I want that the button is usable as a standard WindowsFormsButton.
This includes that I can add the button at design time!
Extending a button control is no different then extending any class in C#. Simply do the following:
class ToggleButton : Button {
// Add your extra code
}
You need to create a class that inherits the System.Windows.Forms.Button class and adds your property and associated behavior.
After compiling your project, your new class will appear in the toolbox.
I know this is old and has been answered - however,
Why make life difficult?
Each control has a Tag property which you can easily set to IsSwitchedOffable - or better English CanBeDisabled
Far easier.
In my puzzle application 2d button's location is to be changed... So i need extra facilities...
My button ButObj extends Button class
Public Class ButObj : Button
{
Point initloc;
Public ButObj(Point loc)
{ this.Location=initloc=loc ; }
Public bool isNearto(ButObj X)
{
if (this.Location.X==X.Location.X || this.Location.Y==X.Location.Y)
return true;
else return false;
}
Public bool isSettled()
{
if(this.Location==initloc)
return true ;
else return false;
}
Public void Replace (ButObj X)
{
Point temp ;
temp=this.Location;
this.Location=X.Location;
X.Location=temp;
}
}
Following code is written in form 1_load ()
ButObj[ ][ ] B=new ButObj[4][4];
char c='A';
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
{ B[i][j]=new ButObj(new Point (i*100+10,j*100+10));
B[j][i].Text = ""+c++;
B[i][j].Font =new Font ("Arial", 24);
this.Controls.Add (B[i][j]);
B[i][j].MouseClick += new MouseEventHandler(MouseClick); }
Coding in mouse click event
private void MouseClick(Object sender, EventArgs e)
{
ButObj b=(ButObj)sender;
if (b.isNearto(B[3][3]))
b.Replace(B[3][3]);
\\ checking after replace
if(AllSolved());\\game over
}
bool AllSolved()
{
for (int i=0;i<4;i++)
for (int j=0;j<4;j++)
if (!B[i][j].isSettled)
return false ;
return true;
}