DataTable descendant with DebuggerDisplay attribute loses DebuggerVisualizer - c#

I have a descendant of DataTable that has the DebuggerDisplay attribute defined. The default visualizer for DataTable is removed when I add the DebuggerDisplay attribute. If I remove the DebuggerDisplay attribute, the DataTable visualizer returns. I want the default DataTable visualizer and my override for DebuggerDisplay.
Do you guys know how to get it working?
//does not work
//[DebuggerVisualizer("Microsoft.VisualStudio.Debugger.DataSetVisualizer", typeof(DataTable))]
//DebuggerDisplay attribute removes DataTable visualizer. Odd behavior to me.
[DebuggerDisplay("{TableName}, Count = {Rows.Count}, {GetColumnNames()}")]
public class MyTable<T> : DataTable where T : class{}

Just to clarify, I've got no idea why deriving and specifying a different attribute disables the visualizer.
I've tried something similar and nothing stops you from having both DebuggerDisplay and DebuggerVisualizer applied to a type. The image below shows both, the left circle is the debugger visualizer, the right circle is the debugger display:
However, you may get issues with trying to use the DataSetVisualizer type on your class. It took a lot of jiggery-pokery, but I ended up with the following definition for my class:
[Serializable]
[DebuggerVisualizer(typeof(EnhancedDataSetVisualizer.DataSetVisualizer),
typeof(EnhancedDataSetVisualizer.DataSetVisualizerSource))]
[DebuggerDisplay("{Name}")]
public sealed class SpecFlowTableWrapper : DataSet
{
// Body omitted, not important.
}
I was constantly having to change what arguments I specified in DebuggerVisualizer. It turns out the missing piece for me was specifying the VisualizerObjectSource.
I then get the debugger display showing my data set name, and when I click the magnifying glass it loads the DataSetVisualizer.
The important part in all this is two references:
Microsoft.VisualStudio.Debugger.DataSetVisualizer
This contains the DataSetVisualizer and DataSetVisualizerSource types.
Microsoft.VisualStudio.DebuggerVisualizers
This is a dependency of the other reference.
The second item is generally available in the "Add References..." dialog in Visual Studio, however the first item is found in the VS installation directory.
For me (VS version may vary):
C:\Program Files (x86)\Microsoft Visual Studio
10.0\Common7\Packages\Debugger\Visualizers\
Called:
Microsoft.VisualStudio.Debugger.DataSetVisualizer.dll
Make sure "Copy Local" is true for the first reference as well (it should be true by default anyway). Note that for debugging, this reference is now a dependency so you need to make sure it is in the working directory of whatever project you are debugging, otherwise you get VS debugger errors.
Re-build, start debugger, enjoy. Sorry it was 2 years late.

Related

Change BuildAction to None in VSIX

So I am currently working on an extension and I want to change the Build Action of a specific ProjectItem to None.
What I tried
I noticed that the ProjectItem had a Properties property which contains the following KeyValuePair wher the key is BuildAction. Therefor I tried to set its Value to prjBuildActionNone which should be the correct value for it.
Anyway, when I hit Play and the code runs and I set a breakpoint on this very line:
prop.Value = "prjBuildActionNone"
The Debugger will never return to the line below and that is it.
Is there anything I am doing wrong with this approach or is this the totally wrong direction and the Properties property is for read-only purposes?
The value should be a member of the prjBuildAction enumeration, e.g. prjBuildAction.prjBuildActionNone.
Execution is not reaching the next line because the incorrect type is causing an exception.

I get [MustUseReturnValue] warning from a method that is not annotated

I can't get rid of one ReSharper warning. I have a bunch of HtmlHelpers including one for table, that allows me to bind view model properties to columns, add html attributes and call some other column-specific functions and I'm using method-chaining.
In the .Columns(Action<ColumnFactory<TSource>> columns) method, I always get the warning: Return value of method annotated with [MustUseReturnValue] attribute is not used
But none of my code is annotated with this atrribute. As you can see in the screenshot, where is definition of the class and I also included search results from the whole solution with zero items found.
The code is mine and it doesn't inherit any 3rd party solution. So it can't come from a compiled assembly.
I thought it could be a problem with Action or Func delegates but this warning doesn't appear in the rest of my helpers that uses similar approach (as you can see at the bottom of the screenshot)
I was trying to find an attribute that would suppress this warning but there doesn't seem to be any. The only solution that works is to disable this warning in ReSharper settings. But I would like this to be enabled so that I can use this attribute and let ReSharper to warn me on other places.
So is it possible that this attribute is in some cases applied implicitly? And how can I get rid of this warning?

C# rule for public fields

I have problem with public fields, which I use from time to time in my code. I keep forgeting to change them to private and create properties for them- especialy when Im testing some new part of code (and Im used to create public field for testing at first).
I was thinking that it would be fine to see some sort of "warning" if I use public field in my code.
I have found out, that I can create a ruleset (Im using Visual Studio Community 2013) and choose any of the rule I need. I searched for the rules relative to public fields and found these 2: CA2211: Non-constant fields should not be visible and CA1051: Do not declare visible instance fields. I checked these in the ruleset, tried to Run code analysis on whole solution but I cant see any warnings in the outcome.
I even tried to add something like public int i; in one of my classes but still nothing.
Do you know if I have the right rules or whether there is something else I should do to get the warning? Thank you.

The specified value cannot be assigned to the collection

Edit
This bugs me for an almost year. I'll update the answer and add bounty.
I've custom control, which has dependency property
public class Graph : Control
{
public List<Figure> Figures
{
get { return (List<Figure>)GetValue(FiguresProperty); }
set { SetValue(FiguresProperty, value); }
}
public static readonly DependencyProperty FiguresProperty =
DependencyProperty.Register("Figures", typeof(List<Figure>), typeof(Graph),
new PropertyMetadata((d, e) => ((Graph)d).InvalidateVisual()));
...
}
Figure is the base class for all figures:
public abstract class Figure { ... }
public class LineFigure : Figure { ... }
public class XGridFigure : Figure { ... }
public class YGridFigure : Figure { ... }
...
Now look at screenshots below to see the problem: sometimes (after doing a change to xaml in other place) designer goes crazy about it and stop rendering the whole window, throwing exceptions, while code compiles and runs without problem. I can close this xaml (designer) and open it again to make problem go away. But it always reappears.
Question: is there something wrong on my side? Missing attribute? Wrong usage? How can I fix that problem?
Old question
Ugly situation.
I have 2 UserControl. In both hand-made control Graph is used. Graph has property Figures to specify List<Figure>. There are dozens of figures which have Figure as base.
In one UserControl it works fine, in other throws exception
The specified value cannot be assigned to the collection. The following type was expected: "Figure".
And I fail to see a difference what could cause a problem.
Here is problematic one screenshot
And here is working one
Despite of errors project compiles and runs, but if I need to do modification to problematic UserControl, then it's not showing any content (says "Invalid Markup"). Graphs are nearly the same, all 8 errors are shown for to just one UserControl.
What should I do? How to troubleshoot such errors? I exclude (completely) any problem with Graph because it runs without a single problem AND it works without problem for another UserControl. Visual Studio designer problem? Using 2013 Express for Windows Desktop.
Indeed the visual designer does not recognize the inheritance from Figure. One solution is to use IList as the Interface type:
public IList Figures
{
get
{
return (IList)GetValue (FiguresProperty);
}
set
{
SetValue (FiguresProperty, value);
}
}
public static readonly DependencyProperty FiguresProperty =
DependencyProperty.Register ("Figures", typeof (IList), typeof (Graph), new PropertyMetadata (new List<object>()));
That might look like a bit strange (because you give up type safetyness). But have a closer look at the WPF classes. They all do it that way (most likely for good reasons). Or WPF even creates collection classes like PathFigureCollection that implement both IList and IList<PathFigure>.
close the project, restart VS and reopen it. does it still list the errors? visual studio often seems to report "phantom errors", but they usually go away if you close and restart etc.
If the custom control is in the same solution or project, Visual Studio builds it (when it considers it necessary) so it can use the control in the designer.
Sometimes this built/cached version gets out of sync with the code files which causes the Xaml parser/syntax checker to get confused and display those wavy red lines.
I have had success with closing and reopening all designers that use the control but that is pretty annoying to keep on doing. In my experience the most reliable solution is to move the control into a separate solution and project and set a 'proper' reference to the dll.
I had a whole load of these errors in one project.
Eventually I found that the project did not have a reference to System.Xaml.
Adding a reference to System.Xaml removed all of the warnings.
The strange thing is that it didn't cause a runtime problem.

How to specify order of debugger visualizers in Visual Studio

I've been working on a debugger visualizer for Visual Studio for some time and while the actual visualizer works fine. The problem is that it always places itself at the top of the visualizer list when examining a variable which really annoys some of the users who rather have Text as the top one (since the top one is also default when opening VS).
I can't find any support for this on DialogDebuggerVisualizer or DebuggerVisualizerAttribute which were my first thoughts so I've been scouring SO/MSDN/Google for information on how to affect the sort order of the visualizers (preferably to put mine last in the list) but to no avail.
Below is how I register my visualizer, it then just shows a form based on the value that is being visualized.
using Microsoft.VisualStudio.DebuggerVisualizers;
[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(Shorthand.VSAddins.JsonVisualizer.JsonVisualizer),
typeof(VisualizerObjectSource),
Target = typeof(string),
Description = "Json Visualizer")]
namespace Shorthand.VSAddins.JsonVisualizer
{
public class JsonVisualizer : DialogDebuggerVisualizer
{
protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
{
var json = objectProvider.GetObject() as string;
var form = new VisualizerForm { Json = json };
windowService.ShowDialog(form);
}
}
}
Does anyone know if it is possible to affect the order of the visualizers or should I just let it be?
I don't think there is a solution. But there is a workaround:
Define your own Text Visualizer and put appropriate DebuggerVisualizer attribute before the attribute of your JsonVisualizer. The result will be that string will be readable by default and Json Visualizer can be chosen. A window with a multi-line textbox is not too much work.
It is probably not even necessary to write visualizer. It should be possible to use internal one but I don't know its name (Which class is used for "Text Visualizer"?).
It will always appear first, by design. The under the hood cast has found the best match for the variable it is reflecting on.
however, you could do either of two things. You could make the visualizer only appear when the sting contains ':'
Or you could use reflection to reorder the visualisers by adding them to the end of the collection in the order you want, then removing the originals from the collection.
For the latter you will most likely have to change the collection from readonly to writable. Via reflection.
There is no reliable source to draw on other than your will to succeed.
I guess that VS 'under the hood' can distinguish between type of string and type of xml quite easily, but Xml is just a string too, so a key question here would be, how does VS tell the difference between the two?
Could you dissect the VS XML visualizer to see how it works (even if you have to use reflector on the DLL to do it, you might get to see the method that works it out)

Categories

Resources