Welcome to MSDN Blogs Sign in | Join | Help

Visual Studio 2010 Beta 2 Known Issues – Part 2

This post continues my unofficial list of known issues in VS 2010 Beta 2 (see Part 1). As we continue getting Beta 2 feedback and investigating issues, it's time for another update on the issues we've been seeing. Please keep in mind that due to the volume of the issues, I'm only mentioning the ones I was involved with or consider important.

Crash during normal editor operation

There is a rare situation where Beta 2 can crash during normal editing or viewing C# source code. Nevertheless, it happens often enough to become top 1 reported crash for C#.

I'm very happy to say that we have identified the root cause and are working on a fix.

Details: This is an extremely complex and hard to reproduce bug involving native code, threading, and working with Task Parallel Library from native code. The new C# IDE feature, Highlight References, is written in managed code and uses TPL (Task Parallel Library) to calculate references on a threadpool thread. However a certain portion of the language service (called the Language Analysis engine) is written in native code, so we had to do some cross-boundary and cross-thread manupulation. Our developers Ian (from C# compiler) and HeeJae (from C# IDE) worked very very hard to investigate the dumps that you folks were sending in and finally they've found the bug. The good news is that as more and more of Visual Studio gets rewritten in managed code, we hope to see less of such bad bugs in the future.

So thanks to you for clicking that "Send Error Report" button – it really helped us to fix the top 1 reported C# crash!

Cannot open C# source file: Error message "The operation could not be completed. Invalid pointer." or "Object reference not set to an instance of an object"

This one is due to the Tools Options Fonts and Colors using a raster font instead of a TrueType font:

http://blogs.msdn.com/visualstudio/archive/2009/10/27/VS-2010-Beta2_3A00_--Workaround-for-Raster-Font-Settings-Issue.aspx

The fix is easy: switch to a TrueType font such as Consolas or Courier New.

The editor team has fixed this one already.

The application cannot start (VS black screen)

Weston writes about this one in detail: http://blogs.msdn.com/visualstudio/archive/2009/10/29/how-to-fix-the-application-cannot-start-error.aspx 

This is due to us being unable to read certain profile settings.

The workaround is basically to run devenv /resetuserdata from the Visual Studio command prompt, but I encourage you to follow the link above for more information (e.g. how to save your settings beforehand).

This is already fixed as well (now even if the profile contains the errors we will start successfully and deal with the errors).

TextOptions does not appear in the IntelliSense in XAML designer

The WPF team has completely rewritten the WPF text rendering to get rid of the font blurryness issue. The old style is still the default, to enable the new mode you need this simple attribute in your XAML: TextOptions.TextFormattingMode="Display". The problem is – TextOptions won't show up in IntelliSense!

The workaround is to ignore IntelliSense and just build your project – things should just work.

This has been fixed as well.

All menus except the File menu disappear

It happens extremely rarely, but we saw it three times already – the menus are just gone!

image

This one is very very hard to reproduce and we're still investigating this right now – for some unknown reason something is messing up the Style or the ControlTemplate for the menus. If you happen to run into this inside a virtual machine, you can really help us investigate the issue by pausing the machine in the state where VS is running and menus are gone.

Feel free to open a bug on http://connect.microsoft.com/visualstudio/feedback or let me know and we'll send you instructions on how to upload the VM image.

Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.VisualStudio.Editor.Implementation.IVsGlobalUndoCapableUndoManager'.

---------------------------

Microsoft Visual Studio

---------------------------

Unable to cast COM object of type 'System.__ComObject' to interface type 'Microsoft.VisualStudio.Editor.Implementation.IVsGlobalUndoCapableUndoManager'. This operation failed because the QueryInterface call on the COM component for the interface with IID '{305E8709-55B7-4732-B872-1C073AB58047}' failed due to the following error: No such interface supported (Exception from HRESULT: 0x80004002 (E_NOINTERFACE)).

---------------------------

OK

---------------------------

 

Right now we can't reproduce it so we're looking for any help – call stack, minidump with heap, ActivityLog.xml etc. You can read more about the ActivityLog here:

http://msdn.microsoft.com/en-us/library/ms241272.aspx

We'd appreciate any help!

Expression.Compile generates incorrect code for (int?) conversion

using System;
using System.Linq.Expressions;

class Program
{
    static void Main()
    {
        Expression<Func<ValueType, int?>> expr = x => (int?)x;
        Func<ValueType, int?> converter1 = x => (int?)x;
        Func<ValueType, int?> converter2 = expr.Compile();

        int? a1 = converter1(null); // (int?) null
        int? a2 = converter2(null); // NRE
    }
}

Expected: both the direct delegate and the one generated with Expression Trees should work identically. Actual: the expression tree one throws a NullReferenceException.

Thanks to controlflow for reporting this! It's a good bug, but unfortunately it will require a risky compiler change that we don't want to take so late in the product cycle. We've postponed the bug for a later release.

Delegate.Combine doesn't support variance

using System;

class A { }
class B : A { }

class Program
{
    static void Main()
    {
        Action<B> b = _ => { };
        Action<A> a = _ => { };
        b += a;
    }
}

 

This program compiles fine but causes an exception at runtime. The CLR team decided to postpone this to a future version.

Completion List doesn't show up for certain lambda parameters in multiple overload scenarios

using System;

using System.Linq;
using System.Threading.Tasks;

class Program
{
    static void Main(string[] args)
    {
        var query = Enumerable.Range(0, 100);
        Parallel.ForEach(query, (i, p) =>
        {
            Console.WriteLine(i);
            p.
        });
    }
}

 

In this code, IntelliSense doesn't show after p. Another great bug from controlflow. We've fixed this one (it had to deal with picking the right overload of ForEach given an incomplete lambda statement).

Debugger data tips are leaking GDI handles

Hovering the mouse cursor over variables during debugging and expanding the nodes in the tips will leak GDI handles. After the Visual Studio process will run out of GDI handles (and each process can only allocate 10,000 handles), it will crash. Usually this happens after 10-15 minutes of intensive debugging with datatips, depending on circumstances. You can watch the GDI handles of the devenv.exe process in the Task Manager (if you select GDI in View –> Select Columns).

This is a stress bug that has been fixed by the debugger team recently.

Tooltips on toolbar buttons are not displaying keyboard shortcuts

As part of the WPF rewrite, we had postponed this work until very late, and only recently have fixed it (post Beta 2). Now all the keyboard shortcuts show up when you hover your mouse over a toolbar button. You will not be able to turn them off though :)

Printing formatted source code with color is not supported

This is actually not a bug, it's by design. We had to cut this low-impact feature from 2010 because of tight resources constraints as we've reimplemented the editor from scratch. This feature will hopefully come back in a later release of Visual Studio, maybe as an add-in.

More High DPI and other accessibility issues

I just keep finding more and more High DPI issues, hoping that if I find and report them now, you guys won't have to.

Combobox missing right edge:

image

The shell team decided not to fix this because of tight schedule and resources.

Snippets background poorly visible on High Contrast Black

image

The editor team has decided not to fix this because the colors are configurable.

Silverlight Out-of-Browser settings dialog clips some controls under 120 DPI

We're looking into fixing this right now.

Posted by Kirill Osenkov | 7 Comments
Filed under: ,

A million-dollar pen vs. a pencil

You know this legend about how NASA spent millions to develop a pen that can write in zero gravity, and the russians have just used a pencil? Well, I was reminded about this by Dejan’s post in response to my post about the Random Gradient Wallpaper Generator.

I used an O(NxN) algorithm to generate a megapixel image that takes up about 5 MB on my desktop.

Dejan generated a 2x2 bitmap that takes up 70 bytes and let Windows stretch it with the exactly same effect. If you read my original post, go read this one, you’ll like it :)

Posted by Kirill Osenkov | 5 Comments
Filed under: ,

Bezier Curves and Car Manufacturers

Michael has asked me if it was possible to add Bezier curves to Live Geometry. So I went ahead and added a Bezier tool (and it took me about 30 minutes to do so!):

image

This draws a cubic Bezier curve using four points:

image

There is something beautiful and elegant about these curves. No wonder industrial designers use it a lot. I actually felt so inspired that I went ahead and used the tool to design a car :) Here's the live view (you need Silverlight 3 to see this), and you can drag the points around:

This is so fascinating. Maybe if I'm tired of programming I should just design cars? ;) Any recruiters from Subaru reading this?
 
I also built in a possibility to pass arguments to Live Geometry using initParams:
<object data="data:application/x-silverlight-2," 
type="application/x-silverlight-2" width="100%" height="100%">
  <param name="source" value="LiveGeometry.xap"/>
  <param name="initParams" 
         value="LoadFile=http://guilabs.de/geometry/drawings/fun/car.lgf,ShowToolbar=false" />
...

That's how I was able to embed Live Geometry into this page so that it doesn't show the toolbar and it automatically loads the car.lgf drawing.

Finally, here are some important things to know if you want to host a .xap file from another domain:

  • That domain must have crossdomain.xml at its root (so http://livegeometry.com/crossdomain.xml should be accessible)
  • If you're testing this by loading an .html file from a local filesystem, it will just display a white background and won't load the app. Put the .html on a webserver, then it will work

Irony

(Ironically, this post is not about irony in it's traditional sense)

Irony (http://irony.codeplex.com) is an open-source .NET compiler construction framework written by Roman Ivantsov. It is a ".NET Language Implementation Toolkit". The language grammar is described in C# (or any other .NET language).

So instead of generating the scanner and the parser from a grammar description written in an external DSL, Irony uses a .NET object graph to host the grammar description (internal DSL), and it uses this in-memory grammar description to drive the scanner and the parser at runtime.

One huge advantage of this approach is that the language description becomes orthogonal to the scanner and parser implementation. Writing and maintaining a language becomes easier. See an example of grammar definition further down in this post.

Arithmetic expression evaluation

The reason I'm talking about all this is that I was looking around for an expression parser for Live Geometry. I was able to compile expressions earlier using DLR, but there were two issues with that.

  1. First, DLR has quite a footprint – adding a dependency on DLR to a Silverlight binary can grow the size of the .xap file from 400 KB to 1400 KB – and that's not good.
  2. Second, DLR didn't seem to expose the parse trees easily – and I do need the access to the parse trees for inspection and manipulation, such as calculating dependencies between formulas.

So I started looking around. There are really a lot of related projects out there, I'll just mention the ones on CodePlex:

  1. http://antlrcsharp.codeplex.com
  2. http://csparser.codeplex.com
  3. http://expressioneval.codeplex.com
  4. http://flee.codeplex.com
  5. http://ilcalc.codeplex.com
  6. http://lazyparser.codeplex.com
  7. http://linqovercsharp.codeplex.com
  8. http://ncalc.codeplex.com
  9. http://simpleexpressioneval.codeplex.com
  10. http://simplemathparser.codeplex.com

There might be more. My requirements were for the tool to output a parse tree and give me full access to it. Another requirement is that the grammar description has to be as simple as possible and as flexible and extensible as possible (because I planned to extend the language with custom elements such as method calls and property access). However full blown C# and LINQ parsers were an overkill. Other good projects were really fast, but didn't give me the parse tree.

So I settled on Irony, and so far I'm pretty happy that I did. It didn't provide the Silverlight version out of the box, but I'm talking with Roman about Silverlight support. For now, it took me an hour to make the Irony sources build for Silverlight and I built a nice little Irony.Silverlight.dll for my own project.

Expression parser in Irony

Here's how I declared the grammar for the language that I need:

// This grammar is based on the ExpressionEvaluatorGrammar from Irony.Samples
// Copyright (c) Roman Ivantsov
// Details at http://irony.codeplex.com
[Language("Expression", "1.0", "Dynamic geometry expression evaluator")]
public class ExpressionGrammar : Irony.Parsing.Grammar
{
    public ExpressionGrammar()
    {
        this.GrammarComments = @"Arithmetical expressions for dynamic geometry.";

        // 1. Terminals
        var number = new NumberLiteral("number");
        var identifier = new IdentifierTerminal("identifier");

        // 2. Non-terminals
        var Expr = new NonTerminal("Expr");
        var Term = new NonTerminal("Term");
        var BinExpr = new NonTerminal("BinExpr");
        var ParExpr = new NonTerminal("ParExpr");
        var UnExpr = new NonTerminal("UnExpr");
        var UnOp = new NonTerminal("UnOp");
        var BinOp = new NonTerminal("BinOp", "operator");
        var PostFixExpr = new NonTerminal("PostFixExpr");
        var PostFixOp = new NonTerminal("PostFixOp");
        var AssignmentStmt = new NonTerminal("AssignmentStmt");
        var AssignmentOp = new NonTerminal("AssignmentOp");
        var PropertyAccess = new NonTerminal("PropertyAccess");
        var FunctionCall = new NonTerminal("FunctionCall");

        // 3. BNF rules
        Expr.Rule = Term | UnExpr | FunctionCall | PropertyAccess | BinExpr;
        Term.Rule = number | ParExpr | identifier;
        ParExpr.Rule = "(" + Expr + ")";
        UnExpr.Rule = UnOp + Term;
        UnOp.Rule = ToTerm("+") | "-" | "++" | "--";
        BinExpr.Rule = Expr + BinOp + Expr;
        BinOp.Rule = ToTerm("+") | "-" | "*" | "/" | "^";
        PropertyAccess.Rule = identifier + "." + identifier;
        FunctionCall.Rule = identifier + ParExpr;
        this.Root = Expr;

        // 4. Operators precedence
        RegisterOperators(1, "+", "-");
        RegisterOperators(2, "*", "/");
        RegisterOperators(3, Associativity.Right, "^");

        RegisterPunctuation("(", ")", ".");
        MarkTransient(Term, Expr, BinOp, UnOp, AssignmentOp, ParExpr);
    }
}

That's it! Note how Irony uses operator overloading for | and + to build rules. We need ToTerm("+") call on any of the operands to give the C# compiler a hint about the types so the operator overloading can succeed. This is a good example of an internal DSL hosted in C#.

Consuming the parse tree

Now, here's how to use the ExpressionGrammar class to create and use a parser:

Grammar grammar = new ExpressionGrammar();
Parser parser = new Parser(grammar);
ParseTree parseTree = parser.Parse("sin(2 * x) + 1");

Producing a LINQ Expression Tree from a parse tree

Now, given the parse tree from the previous step, I just quickly wrote an ExpressionTreeBuilder that produces a bound expression tree out of it, and a Binder that helps resolve names. The Compiler class is a façade for the whole thing:


public class Compiler
{
    public static Func<double, double> CompileFunction(string functionText)
    {
        ParseTree ast = ParserInstance.Parse(functionText);
        ExpressionTreeBuilder builder = new ExpressionTreeBuilder();
        Expression<Func<double, double>> expression = builder.CreateFunction(ast.Root);
        Func<double, double> function = expression.Compile();
        return function;
    }

    static Parser ParserInstance = new Parser(ExpressionGrammar.Instance);
}


public class Binder { public void RegisterParameter(ParameterExpression parameter) { parameters.Add(parameter.Name, parameter); } ParameterExpression ResolveParameter(string parameterName) { ParameterExpression parameter; if (parameters.TryGetValue(parameterName, out parameter)) { return parameter; } return null; } Dictionary<string, ParameterExpression> parameters = new Dictionary<string, ParameterExpression>(); public Expression Resolve(string identifier) { return ResolveParameter(identifier); } public MethodInfo ResolveMethod(string functionName) { foreach (var methodInfo in typeof(System.Math).GetMethods()) { if (methodInfo.Name.Equals(functionName, StringComparison.InvariantCultureIgnoreCase)) { return methodInfo; } } return null; } }

public class ExpressionTreeBuilder
{
    public ExpressionTreeBuilder()
    {
        Binder = new Binder();
    }

    public Binder Binder { get; set; }

    public Expression<Func<double, double>> CreateFunction(ParseTreeNode root)
    {
        ParameterExpression parameter = Expression.Parameter(typeof(double), "x");
        Binder.RegisterParameter(parameter);
        Expression body = CreateExpression(root);
        var result = Expression.Lambda<Func<double, double>>(body, parameter);
        return result;
    }

    Expression CreateExpression(ParseTreeNode root)
    {
        if (root.Term.Name == "BinExpr")
        {
            return CreateBinaryExpression(root);
        }

        if (root.Term.Name == "identifier")
        {
            return Binder.Resolve(root.Token.Text);
        }

        if (root.Term.Name == "number")
        {
            return CreateLiteralExpression(Convert.ToDouble(root.Token.Value));
        }

        if (root.Term.Name == "FunctionCall")
        {
            return CreateCallExpression(root);
        }

        return null;
    }

    Expression CreateCallExpression(ParseTreeNode root)
    {
        string functionName = root.ChildNodes[0].Token.Text;
        Expression argument = CreateExpression(root.ChildNodes[1]);
        MethodInfo method = Binder.ResolveMethod(functionName);
        return Expression.Call(method, argument);
    }

    Expression CreateLiteralExpression(double arg)
    {
        return Expression.Constant(arg);
    }

    Expression CreateBinaryExpression(ParseTreeNode node)
    {
        Expression left = CreateExpression(node.ChildNodes[0]);
        Expression right = CreateExpression(node.ChildNodes[2]);

        switch (node.ChildNodes[1].Term.Name)
        {
            case "+":
                return Expression.Add(left, right);
            case "-":
                return Expression.Subtract(left, right);
            case "*":
                return Expression.Multiply(left, right);
            case "/":
                return Expression.Divide(left, right);
            case "^":
                return Expression.Power(left, right);
        }
        return null;
    }
}

This just demonstrates the principle. One could easily extend this to write a full blown expression compiler, but this is good enough for my purposes for now. Live Geometry now uses this to evaluate math expressions and plot function graphs. As always, you can get the source from here.

Posted by Kirill Osenkov | 3 Comments
Filed under: ,

Indexed Properties in C# 4.0

Executive summary:

  1. In C# 4.0 you can call parameterized properties declared in COM using the indexer syntax, for instance instead of excel.get_Range("a") you can now write excel.Range["a"].
  2. You can’t declare your own indexed properties from C#. We have no plans of adding the ability to declare your own properties with parameters. Instead, the recommended way is to use a type with an indexer.
  3. The feature is immediately available in Visual Studio 2010 Beta 2 for your indexing pleasure.

So I guess this hasn’t had a lot of press coverage so far (although Sam hinted about it). Even the published C# 4.0 language specification and the C# Future page still don’t mention it as of now. This is because we’ve implemented this feature very late in the cycle, as a DCR (Design Change Request). The language design team felt that we should complete the COM interop story in 4.0 and this one was the last missing piece of the puzzle. When Paul was in Redmond this summer, he was tasked with testing the IDE support for this feature, and I was helping out with the test infrastructure.

The new syntax

The pattern is very simple. Wherever you use COM interop and have to call get_X() and set_X(), now you can just call X[], which we feel is a more natural syntax:

// before
excel.get_Range("A1").set_Value(Type.Missing, "ID");

// after
excel.Range["A1"].Value = "ID";

Let’s also take Scott Hanselman’s example from Beta 1:

var excel = new Excel.Application();
excel.Visible = true;
excel.Workbooks.Add();
excel.get_Range("A1").Value2 = "Process Name";
excel.get_Range("B1").Value2 = "Memory Usage";

Now you can simplify this even further:

var excel = new Excel.Application();
excel.Visible = true;
excel.Workbooks.Add();
excel.Range["A1"].Value = "Process Name";
excel.Range["B1"].Value = "Memory Usage";

 

This is just syntactic sugar – the compiler emits calls to the get_ and set_ accessors behind the stage.

Omitting []

In case that all the parameters are optional and none of the arguments are specified, you should omit the empty []. Having Value[] is illegal.

This is the reason you can replace Value2 with Value in the example above: Value is an indexed property and you’re calling it without specifying any arguments – in this case we omit the brackets [] altogether. Earlier, without indexed properties support, we had to introduce the ugly Value2, because you otherwise had to call get_Value().

IDE support

My team, on the IDE side, provided IntelliSense support for this new language feature:

  • completion list:

image

  • parameter help:

image

  • however Quick Info still shows you that in reality the call simply binds to the get_Range method:

image

As we were designing the feature, it turned out that adding compiler support for it is not the only tricky part. There were a couple of interesting problems in the IDE space as well. For example, what do you show in Quick Info for the following intexed property call?

A.B[C]++;

Do we now show get_B or set_B?

When the IDE can’t guess which accessor we’re talking about (for example, in incomplete code), we by default bind to the get_accessor.

Backwards compatibility

For backwards compatibility reasons, using the accessors get_ and set_ directly is still valid and available in IntelliSense, because we didn’t want to break all existing COM interop code out there.

Why not allow declaring indexed properties in C#?

A common question that we expect we’ll be getting is “why just consume? why not allow to declare such properties in C#?”. Well, the answer is not even that we first have to cost, design, spec, prototype, implement and test this feature, but rather that we think that declaring a type with an indexer is a preferred approach. It’s useful to separate the responsibilities:

  • The property is there to get an object. The property belongs to the parent object.
  • The indexer is there on the returned object to enumerate it. The indexer belongs to the returned object.

We shouldn’t be mixing these together.

Static or dynamic?

Accessing indexed properties is supported from both static and dynamic code.

kick it on DotNetKicks.com

Visual Studio 2010 Beta 2 Known Issues

[This is Part 1. Read Part 2 here]

Now that we’ve shipped Beta2 and the world is busy downloading the fresh new bits, I’m very excited to know what do you guys think? Will you like it? Will there be major issues that we missed? Time will show :)

By definition, this Beta 2 release is not final, and there are still bugs lurking around out there. We are very busy fixing those bugs for RTM, but for now, there are some that we haven’t had time to fix before Beta2.

This post lists some of the known issues that are in VS 2010 Beta 2. It’s not in my powers to maintain a comprehensive list here, I’ll just mention the ones which I was personally involved with in my day-to-day work. Apologies that I have found them too late, but I guess better late then never...

Updates – new!

Posted the Part 2 of the issues (updated 11/12/2009)

http://blogs.msdn.com/kirillosenkov/archive/2009/11/12/visual-studio-2010-beta-2-known-issues-part-2.aspx

All further updates will happen there or will wait until Part 3.

The official Beta2 known issues list (updated 10/26/2009)

http://go.microsoft.com/fwlink/?LinkID=166199

Updating the .sln file from Beta1 to Beta2 (updated 10/26/2009)

Need to upgrade .sln file from Beta2 in order to be able to double-click it. See Jon’s post here for more details:

http://msmvps.com/blogs/jon_skeet/archive/2009/10/26/migrating-from-visual-studio-2010-beta-1-to-beta-2-solution-file-change-required.aspx

Setup dialog UI layout wrong on High DPI

image

Embarrassing! Unfortunately, not everyone on the Visual Studio team is rigorous about non-default testing, such as High DPI, Accessibility, etc. We will hopefully fix this one before RTM. Also recent data shows that non-96 DPI is a very common setting, a lot of people actually use 120 DPI and others. I personally use 120 DPI, that’s how I find these bugs.

SmartTag high DPI issues

image

With high DPI, the SmartTag menu is missing horizontal menu separator bars. Also the right vertical edge of the SmartTag button disappears. These bugs are a recent regression from WPF introducing the UseLayoutRounding API. The WPF team is looking into fixing these issues before the release.

QuickInfo tooltip trimmed at high DPI

image

This is another regression from the new DWrite technology. The last word in the tooltip is missing! This one is fixed already.

Thin line on top of the active document tab

image

Again, another high DPI issue. You can only notice this one if you look closely. We’ve fixed this already as well.

Outlining Expand/Collapse glyphs are shifted several pixels up

image

Fixed already. A lot of people complained about this internally.

Zoom combobox in the bottom-left corner of the editor isn’t aligned with the horizontal scrollbar

image

This is fixed.

Don’t tear off the Call Hierarchy tool window!

When you try to undock the C# Call Hierarchy toolwindow and drag it away (for example, to another monitor), VS will crash. This one is too embarrassing, because I was the one who is responsible for testing Call Hierarchy. To my defense, I was on vacation when this regressed and when I came back and found this, it was too late to fix. Shell UI team changed something about the WPF toolwindow implementation and we had some layout logic that didn’t expect double.Infinity as an argument, so we crashed. This one’s already fixed in recent builds.

Vertical separator bar in the Call Hierarchy tool window doesn’t resize the details pane

This also only reproes under 120 DPI and above. You can’t resize the two panes below by dragging the vertical bar:

image

And again, this is one that I should have caught and missed. When I caught this, it was too late to fix for Beta2. The WPF team is looking at this one right now.

Error message connecting to a TFS server via HTTPS

Well, guess what, the TFS client team has done it again! TFS HTTPS story was broken in Beta1, and it still has a bug in Beta2. However the good news is that there is a really easy workaround this time.

When adding a new TFS HTTPS webserver (e.g. a Codeplex server at http://codeplex.com), after entering your credentials you will see this:

image

Don’t panic! Just enter your credentials again and things will work just fine. If you used the Tip (http://blogs.msdn.com/kirillosenkov/archive/2009/09/27/tip-don-t-enter-your-codeplex-credentials-every-time.aspx), then you will be unaffected by this and things will hopefully run smoothly.

Ctrl+Alt+DOWN ARROW doesn’t bring up the active document list

Ctrl+Alt+Down used to bring up the active document list, in Beta2 it doesn’t. This is fixed.

Start Page: scroll wheel doesn’t work at the news feed

Also the scrollbar thumb only moves in discrete steps. The Shell UI team decided not to fix this, because they don’t have time and resources for this. I actually was surprised to discover that the scrollbar didn’t work in 2008 either. Never noticed this until recently.

VS Command prompt shortcut is not getting installed if you don’t install C++

This one will be fixed as well.

Hovering over ‘var’ during debugging doesn’t show the inferred type

Jeffrey Richter told me about this minor annoyance. Although our language service correctly reports the inferred type when you hover the mouse cursor over ‘var’ in design time, it doesn’t work in debug mode. Since Jeff teaches a lot of courses in debugging and threading, this was bugging him ever since we shipped C# 3.0. Well, we finally fixed it for 2010 RTM. Thanks to Jeff for reporting this!

Visual Studio doesn’t start maximized when first launched

A while back I’ve logged a bug against the Shell team to “just start VS maximized for heaven’s sake”. They did the fix, but somehow it didn’t make it into the Beta2 branch. They’ll hopefully fix this for RTM.


Well, these were the ones worth mentioning I guess. Apologies if you run into any of these or any other bugs for that matter. I will keep updating this post with more issues that I find or I think users should be aware of. Please keep in mind that this is an unofficial list.

Please do let us know about any issues you find by submitting a connect bug. If the bug/suggestion/feedback is related to the C# language or IDE, also feel free to let me know directly or leave a comment on this blog. Since I work closely with the VS editor team, it’s worth watching their blog and giving them feedback: http://blogs.msdn.com/vseditor. Also, if you have any feedback about the new text rendering in WPF 4.0 and Visual Studio, the WPF Text team has a blog here: http://blogs.msdn.com/text.

Saving images (.bmp, .png, etc) in WPF/Silverlight

I’ve recently added a new feature to Live Geometry that allows users to save the current drawing as a bitmap or a .png file. Just push the save button and pick the desired image format in the Save dialog:

image

Fortunately, both WPF and Silverlight support saving full visual contents of any visual into a file on disk. However the approach is somewhat different.

Saving images in WPF

WPF can save any Visual to an image and it supports several formats out of the box via a concept of Encoders. Here’s a sample for .bmp and .png:

void SaveToBmp(FrameworkElement visual, string fileName)
{
    var encoder = new BmpBitmapEncoder();
    SaveUsingEncoder(visual, fileName, encoder);
}

void SaveToPng(FrameworkElement visual, string fileName)
{
    var encoder = new PngBitmapEncoder();
    SaveUsingEncoder(visual, fileName, encoder);
}

void SaveUsingEncoder(FrameworkElement visual, string fileName, BitmapEncoder encoder)
{
    RenderTargetBitmap bitmap = new RenderTargetBitmap(
        (int)visual.ActualWidth,
        (int)visual.ActualHeight,
        96,
        96,
        PixelFormats.Pbgra32);
    bitmap.Render(visual);
    BitmapFrame frame = BitmapFrame.Create(bitmap);
    encoder.Frames.Add(frame);

    using (var stream = File.Create(fileName))
    {
        encoder.Save(stream);
    }
}

These types are all in System.Windows.Media.Imaging.

Saving images in Silverlight 3

In Silverlight, the encoders don’t come as part of the Silverlight runtime – but fortunately there is a project on CodePlex called ImageTools (http://imagetools.codeplex.com) that provides necessary support. You will need to download the following binaries and add them as references to your Silverlight project:

  • ICSharpCode.SharpZipLib.Silverlight
  • ImageTools
  • ImageTools.IO
  • ImageTools.IO.Png (only if you want .png support)
  • ImageTools.IO.Bmp (only if you want .bmp support)
  • ImageTools.Utils

After that, you can call the ToImage() extension method on any Canvas:

void SaveAsPng(Canvas canvas, SaveFileDialog dialog)
{
    SaveToImage(canvas, dialog, new PngEncoder());
}

void SaveAsBmp(Canvas canvas, SaveFileDialog dialog)
{
    SaveToImage(canvas, dialog, new BmpEncoder());
}

void SaveToImage(Canvas canvas, SaveFileDialog dialog, IImageEncoder encoder)
{
    using (var stream = dialog.OpenFile())
    {
        var image = canvas.ToImage();
        encoder.Encode(image, stream);
    }
}

Since you can’t write to disk directly in Silverlight, you can pass a SaveFileDialog and use its stream, or you can obtain a stream elsewhere and pass that. The ToImage() extension method does the dirty work that we had to do ourselves in WPF.

Big thanks to http://imagetools.codeplex.com for their awesome library and encoders!

Links

There are several good folks out there who regularly accumulate interesting links about all things .NET and other stuff on their blogs (cast in alphabetical order):

Alvin Ashcraft

Alvin Ashcraft's Morning Dew

.NET Development Resources from a Progressive.NET Perspective

Arjan Zuidhof

Arjan’s World

Arjan Zuidhof’s opinionated linkblog, with a hang to Alt.NET

Charlie Calvert

Charlie Calvert's Community Blog

Charlie is the C# Community Program Manager on our team and has a great series called “Community Convergence”. I hope he never runs out of roman numerals :)

Chris Alcock

Reflective Perspective

The caffeine fueled thoughts of a UK Software Developer and home of ‘The Morning Brew’

Jason Haley

Interesting Finds

Ramblings of a .Net developer
.ver 3:0:0:0

Scott Guthrie

ScottGu’s Link Listing tag

Yes, ScottGu is a linkblogger!

Steve Pietrek

A Continuous Learner’s weblog

My continuous learning of .NET, C#, VB.NET, ASP.NET, Delphi, Business Intelligence, Software Design and Development, Project Management, Object Oriented Development, Unit Testing, Development Tools ramblings....

And since I feel a little linkbloggy myself today, here it goes:

Posted by Kirill Osenkov | 0 Comments
Filed under:

Visual Studio 2010 New Editor screenshot

I’m very happy with how the Visual Studio editor improved since Beta1:

image

This is all WPF and includes the WPF 4.0 text rendering changes (DWrite integration). Note the new Zoom combobox in the bottom-left (which is the visual counterpart of Ctrl+ScrollWheel). Also the cross to close the tab is now located ON the tab, and not on the rightmost edge of the document. It takes about a day to get used to, but after you get used to it, it’s really awesome.

I believe that the editor team has done a phenomenal job making the editor better for all of us. Note that although the screenshot was made from a remote desktop to a virtual machine, it still looks much better than in Beta1. And believe me, it is way faster and more reliable now.

I’m very excited for Beta2 and can’t wait to get the bits out for you to play with!

Posted by Kirill Osenkov | 18 Comments
Filed under: ,

Random Gradient Wallpaper Generator

Oops, I did it again :) Created a new CodePlex project, that is.

Introducing http://wallpaper.codeplex.com – a simple tool to generate a nice random wallpaper and display it on your desktop with just one click:

WallpaperGenerator1.png

WallpaperGenerator3

  • Randomize - assigns random colors to all four corners
  • Set as Wallpaper - saves the picture to My Pictures\GradientWallpaper.bmp and sets the Windows Desktop wallpaper to this file. It will overwrite the file if it exists.
  • Save colors to text file - appends the RGB values of the current colors to the "colors.txt" log file in the program's directory (in case you liked the colors and want to save the colors, not the image)
You can also click on each of the four corners and pick any color yourself. There are a total of 79228162514264337593543950336 possible wallpapers that can be generated this way.

WallpaperGenerator4WallpaperGenerator5WallpaperGenerator6WallpaperGenerator7WallpaperGenerator8WallpaperGenerator9WallpaperGenerator10WallpaperGenerator11

I wrote this in an evening a couple of years ago and it was just lying around, so I decided to publish it so that it doesn’t get lost. Of course, one could take WPF, MEF, Bling, pixel shaders and build it out into a super-extensible plug-in-based photoshop-like fractal-ray-tracing rendering wallpaper generator, but... For now, let’s stick with a simple WinForms app. But hey, it’s open source, feel free to contribute if you like ;)

Posted by Kirill Osenkov | 8 Comments
Filed under:

Dump Environment Folder Paths

This is just a quick snippet to dump the value of Environment.GetFolderPath for all special folders on a machine (so I don’t have to write it again next time):

public static string DumpEnvironmentPaths()
{
    var paths = Enum.GetValues(typeof(Environment.SpecialFolder))
        .Cast<Environment.SpecialFolder>()
        .Select(folder => folder + " = " + Environment.GetFolderPath(folder))
        .Aggregate((line1, line2) => line1 + Environment.NewLine + line2);
    return paths;
}

Also, I’m using the opportunity to give Rick Strahl’s CodePaste.NET service a spin: http://codepaste.net/uo7zx8.

“CodePaste.NET is a public site for pasting snippets of code and linking to them from social network sites.”

As for the code itself (envisioning potential rotten tomatoes flying my way), several things are probably worth mentioning:

  1. First, the code is written in a more functional style, being more explicit about its intent. I think it shows more clearly the input data and the output data, how the data flows and what operations are performed on the input data.
  2. Second, I have a temporary local variable instead of returning the expression immediately. This is for easier debugging, because if you don’t have a temporary variable, you won’t be able to view the return value of the method easily in the debugger. With a temporary local, you can put a breakpoint on the return statement and inspect the results of the query. Someday the tools will be improved and will allow to inspect the return value of methods.
  3. I’m using Aggregate instead of string.Join or StringBuilder because it composes better. On large data volumes, this approach is horrible because it will allocate a ridiculous amount of unnecessary intermediate strings. StringBuilder and string.Join are much more frugal in this respect, so don’t use Aggregate with strings this way. However, in this particular example, the number of strings is O(1), so I just picked the approach that composes better. Unfortunately, string.Join doesn’t compose well at all and was never intended to be used in a fluent API.
Posted by Kirill Osenkov | 7 Comments
Filed under: ,

Tip: Don’t enter your CodePlex credentials every time

I just ran across an awesome tip at Scott’s blog that is going to save me a whole lot of time: Save Your Codeplex Repository Credentials

I was entering my username and password everytime I connected to a CodePlex TFS server. Now I don’t have to!

P.S. To make this work on XP, go to Control Panel –> User Accounts –> click your account –> in the leftmost pane click Manage My Network Passwords:

image

image

Posted by Kirill Osenkov | 0 Comments
Filed under:

ColorPicker Control for WPF/Silverlight

A while back I was looking around for a color picker control for Live Geometry. The ColorPicker from http://silverlightcontrib.codeplex.com was exactly what I was looking for:

(live preview needs Silverlight 3.0)

Using the control in your code

I just took the source from CodePlex and embedded it in my project. You need 5 files:

image

Alternatively, you can reference the binary which you can download from the SilverlightContrib CodePlex project site. Pay attention that generic.xaml contains the template for the control, so don’t forget the xaml. The control will work just fine with WPF and Silverlight, which is really a great thing, especially if you’re multitargeting.

To include the control in your application, here’s the basic code:

<sc:ColorPicker SelectedColor="LightGreen" />

Don’t forget to add an XML namespace:

xmlns:sc="clr-namespace:SilverlightContrib.Controls"

How does the gradient work?

The source code for this control is very good for educational purposes. For instance, I had no idea how they create the big gradient for every possible hue. Well, it’s genius and it’s simple. In generic.xaml:

<Canvas Canvas.Top="0" Canvas.Left="20">
    <Rectangle x:Name="ColorSample" Width="180" Height="180" Fill="Red"></Rectangle>
    <Rectangle x:Name="WhiteGradient" IsHitTestVisible="False" Width="180" Height="180">
        <Rectangle.Fill>
            <LinearGradientBrush StartPoint="0,0" EndPoint="1,0">
                <GradientStop Offset="0" Color="#ffffffff"/>
                <GradientStop Offset="1" Color="#00ffffff"/>
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
    <Rectangle x:Name="BlackGradient" IsHitTestVisible="False" Width="180" Height="180">
        <Rectangle.Fill>
            <LinearGradientBrush StartPoint="0,1" EndPoint="0, 0">
                <GradientStop Offset="0" Color="#ff000000"/>
                <GradientStop Offset="1" Color="#00000000"/>
            </LinearGradientBrush>
        </Rectangle.Fill>
    </Rectangle>
    <Canvas x:Name="SampleSelector" IsHitTestVisible="False" Width="10" Height="10" Canvas.Left="100" Canvas.Top="96">
        <Ellipse Width="10" Height="10" StrokeThickness="3" Stroke="#FFFFFFFF"/>
        <Ellipse Width="10" Height="10" StrokeThickness="1" Stroke="#FF000000"/>
    </Canvas>
</Canvas>

This canvas contains layers like in a cake. ZIndex of objects is stacked bottom to top, so the solid rectangle with initially red background is on the bottom.

Above it, there is a horizontal white gradient fill, completely white on the left and completely transparent on the right.

Above it, there is a vertical black gradient fill, completely black on the bottom and completely transparent on the top.

As these gradients overlay, the transparency over the initial solid background creates the desired effect – the actual color is in top-right, where both gradients are 100% transparent. The white spot is in top-left, where the white gradient is most intense and black gradient fades out. Same for the black edge of the gradient.

Also, it is well worth studying how the template is written – I learned a lot from this sample.

My fixes

Since I conveniently borrowed the source code for my project, I did several fixes for my own purposes. Ideally I should contribute the fixes back to SilverlightContrib, but I can never get around to it.

First of all, I reordered the two StackPanels in the template so that the actual selected color is on top. I also made it collapsible and collapsed by default. You can expand the control by clicking it like a combobox. Unlike a combobox, you have to explicitly click the color area to collapse it again.

I’ve enabled this by adding an Expanded property:

public bool Expanded
{
    get
    {
        return m_chooserArea.Visibility == Visibility.Visible;
    }
    set
    {
        var visibility = value ? Visibility.Visible : Visibility.Collapsed;
        if (m_chooserArea.Visibility == visibility)
        {
            return;
        }
        m_chooserArea.Visibility = visibility;
    }
}

When clicking on the color area, I just call Enabled = !Enabled to toggle it and it does the magic for me. The default value for this is obviously the default visibility of m_chooserArea, which is specified in XAML template (Visibility=”Visible” to set to true by default).

Other fixes are not as interesting. I fixed a division by zero in ColorSpace.ConvertRgbToHsv (they had h = 60 * (g - b) / (max - min); and didn’t check if min == max). There are a couple of other things which I don’t remember off the top of my head. I’d have to view TFS history to remember what those were. If you’re willing to help and incorporate these fixes to the original project, I’ll dig this up, just let me know :)

Conclusion

Both Sara Ford and myself agree that this control deserves both thumbs up:

image

Reflection with dynamic

This past summer the Visual C# IDE team was fortunate enough to have Paul van Brenk intern with us. Paul is a great guy and an experienced .NET developer from Rotterdam, Netherlands, who is interested in Azure, cloud computing and many other things. He also happens to be one of the contributors for dasBlog, which I think is seriously cool.

Paul and I were sharing an office during his internship and I was the “coach”, i.e. the guy who gets to answer all intern’s questions and helps figure things out :)

Anyway, once we were talking about how to simplify the mess of calling private members using reflection and dynamic came into conversation. So Paul went ahead and wrote some C# 4.0 code that greatly simplifies calling private members using dynamic. Check out his blog: http://www.paulvanbrenk.com/blog/2009/05/30/UsingDynamicForEvil.aspx

There are several things I’d like to shed more light on.

Dynamic usage scenarios

It’s a common misconception that dynamic can only be used for narrow interop scenarios. People came up with ways to use dynamic in a lot more scenarios.

A common theme emerges from such usages: delay the name resolution (binding) to runtime. Instead of hardcoding the symbols known to compiler, we just specify source strings that have to be used at a later stage at runtime for lookup.

Dynamic gives you nicer syntax to express member calls – you express them in your code using usual C# syntax (but without type checking), and the compiler does the heavy lifting of “quoting” the code down to the runtime. If you inspect the generated code, you will see that the compiler is taking your neat member call syntax and generating a complex call site data structure that contains metainformation about the call.

How the language design team designed the dynamic feature

From previous versions of C# you will notice that the language design team is clever when adding new features. They don’t just hardcode a feature into the language, they define an interface and implement the feature against that interface. Not literally, mind you. On the contrary, they rather use duck-typing in most cases, but still there is a contract defined somewhere and the feature works against that contract. Let me give a couple of examples:

  • foreach – they could have added foreach just to arrays. Instead, they “designed against an interface” and said: foreach will work against any IEnumerable implementation. Moreover, the contract of the feature is actually broader and is specified using duck-typing and not an explicit interface. foreach actually works against anything that has a GetEnumerator method, it does not have to implement IEnumerable. The extensibility here is that you can plug-in your own enumerator whatever it is and foreach will work just fine with it.
  • LINQ – again, the language design team said: query syntax will just translate into a well-defined set of methods (Select, Where, etc.). The extensibility here is that you can define your own Select, Where, etc. and LINQ will rewrite the query expressions against your own methods – the queries will continue to just work with your own implementation of the query pattern.
  • dynamic – and here, in C# 4.0, they didn’t just add dynamic. They defined an abstraction layer (an interface) that allows you to plug in your own implementation and the feature (dynamic) will work fine with it.

In other words, they encapsulated an object with runtime callable members into an interface (IDynamicMetaObjectProvider) and provided default base implementation (DynamicObject). What this gives you is the ability to plug in your own implementation and dynamic will work against it.

Effectively, this means that you can intercept member calls on any object, if these calls are dynamic. The secret of “abusing” dynamic is to use member call syntax for stuff other than calling a method. By redefining DynamicObject members you handle member calls in any way you want (usually some sort of lookup by string) – dictionary lookup, XML element and attribute lookup, reflection MemberInfo lookup, and so on.

Now whether this all is good or bad is a totally separate discussion.

Posted by Kirill Osenkov | 0 Comments
Filed under: , , ,

First videos of the structured editor prototype

Disclaimer: the structured editor work described in my posts is unrelated to my work at Microsoft. Everything shown is my personal research done as part of my MSc thesis during 2004-2007. Also, it’s not ready for real use and does not cover all the features of even C# 1.0. It’s a concept prototype and work in progress.

Introduction

As part of my research back in school I was building an experimental structured editor for C#. Now I’ve decided to publish the sources and binaries on CodePlex:

http://structurededitor.codeplex.com

A detailed discussion of structured editors deserves a separate post, which is coming soon. For now, to give a better idea of how the editor works, I’ve recorded six short videos showing the different features below. If your blog reader doesn’t support iframes, I recommend you view this post in the browser.

What is a structured editor?

Programs are represented as text by most code editors. Structured editors, on the contrary, directly display the syntax tree of a program on screen and allow the user to manipulate the tree directly (think MVC: program parse tree is a model, the editor displays a view of it):

This way the visual layout better illustrates the structure of the program and allows for atomic operations on the language constructs. A structured editor lets developers avoid syntax errors and concentrate on the meaning of the program instead of formatting.

1. Introduction

2. Editing

You will notice that there is no intellisense and coloring at the expression level – I did build a SharpDevelop add-in that hosts the structured editor control inside the SharpDevelop project system (DOM), but these videos were recorded on a stand-alone version of the structured editor control hosted inside an empty windows form. Also the support at the expression level is rudimentary, because so far I’ve concentrated the most at declaration level (namespaces, types, members) and statement level (except for single-line statements such as assignments).

 

3. Drag & Drop Support

4. No Parser Means Less Syntax

5. Properties

6. Modifiers

Background

Structured editing is a topic surrounded with scepticism and controversy for the past 20-30 years. Some argue that directly editing the AST on screen is inflexible and inconvenient, because the constraints of always having a correct program restrict the programmer way too much. Others expect structured editors to be more helpful than text editors because the user operates atomically and precisely on the language constructs, concentrating on the semantics and not on syntax.

In summer 2004, my professor Peter Bachmann initiated a student research project - we started building a structured editor for C#. I took part because I was deeply persuaded that good structured editors can actually be built, and it was challenging to go and find out for myself. After the original project was over, I took over the basic prototype and evolved it further to the state it is today.

As one of numerous confirmations for my thoughts, in 2004, Wesner Moise wrote:

...I see a revolution brewing within the next three years in the way source code is written.

Text editors are going to go away (for source code, that is)! Don't get me wrong, source code will still be in text files. However, future code editors will parse the code directly from the text file and will be display in a concise, graphical and nicely presented view with each element in the view representing a parse tree node. ...

I remember how I agreed with this! After three years, in 2007, the prototype implementation was ready - it became the result of my master's thesis. I still agree with what Wesner was envisioning in 2004 - with one exception. Now I believe that structured editors shouldn't (and can't) be a revolution - fully replacing text editors is a bad thing to do. Instead, structured editors should complement text editors to provide yet another view on the same source tree (internal representation, or AST).

My conclusions about structured editors

  1. Text-based editors aren’t going away anytime soon.
  2. Structured editors can only succeed by evolution, not revolution – hybrid approach and ability to toggle between text and structure is the way to go.
  3. The main difficulty with structured editors is getting the usability right.
  4. The right approach is solving all the numerous little problems one by one – find a solution for every situation where a text editor is better (from my experience, for any advantage of a text editor, a good structured solution can be found).
  5. You need a graphical framework with auto-layout such as WPF to build a structured editor.
  6. Don’t try to build a universal editor editor that can edit itself – this approach is too complex. Take a specific language and build a hardcoded editor for this language first. Only after you’ve built 2-3 successful editors, it makes sense to generalize and build a universal editor or an editor generator.
  7. Compilers shouldn’t be a black box, but expose the data structures as a public API surface.
  8. Syntax trees should be observable so that the editor can databind to them.
  9. Traditional expression editor should be hostable inside a structured editor for single-line statements and expressions.

As a result of my work, I'm convinced that structured editors actually are, in some situations, more convenient than text editors and providing the programmer with two views on the code to choose from would be a benefit. Just like Visual Studio Class Designer - those who want to use it, well, just use it, and the rest continues to happily use the text editor. All these views should co-exist to provide the programmer with a richer palette of tools to chooce from.

Hence, my first important conclusion. A program's internal representation (the AST) should be observable to allow the MVC architecture - many views on the same internal code model. With MVC, all views will be automatically kept in sync with the model. This is where for example something like WPF data-binding would come in handy.

As for the structured editor itself - it is still a work in progress and I still hope to create a decent complement for text editors. It has to be usable and there are still a lot problems to solve before I can say: "Here, this editor is at least as good as the text editor". But I managed to solve so many challenging problems already, that I'm optimistic about the future.

Current implementation

The current implementation edits a substantial subset of C# 1.0 - namespaces, types, members (except events), and almost all statements. If you're interested, you can read more at http://www.guilabs.net and www.osenkov.com/diplom - those are two sites I built to tell the world about my efforts. I also accumulate my links about structured editing here: http://delicious.com/KirillOsenkov/StructuredEditors

More languages

It turned out that it makes sense to build structured editors not only for C#, but for other languages as well - XML, HTML, Epigram, Nemerle, etc. That is why, at the very beginning, the whole project was split in two parts - the editor framework and the C# editor built on top of it.

Links

  1. http://structurededitor.codeplex.com
  2. http://guilabs.net
  3. http://www.osenkov.com/diplom
  4. http://delicious.com/KirillOsenkov/StructuredEditors

If you want to know more, or if you want to share your opinion on this, please let me know. I welcome any feedback! Thanks!

kick it on DotNetKicks.com Shout it
More Posts Next page »
 
Page view tracker