Monday, March 23, 2020

Open URLs in the error/warning description

It can be more effort than it feels necessary to navigate to a URL in a message description.

To get to it you might type it into a browser, or more likely, copy the whole message and then copy the URL and then paste it into a browser.

But, you're a busy developer. You have better things to spend your time on than unnecessarily cutting and pasting URLs that you can't easily open.

What you need is a way to open that URL in a browser without all the faff.

Congratulations, you're in luck. I've just updated my Error Helper extension to enable just this scenario.

After you install the extension, you can simply right-click on the entry in the error list and select Open URL. I'm sure you can guess what will happen then ;)
What could be simpler?

And for the avoidance of any doubt, the other options highlighted above will copy the description of the selected entry into the clipboard or search for the description in your default browser.

If you haven't already go install it now.

Don't just take my word for it, here's what others have said.

Thursday, March 19, 2020

Controversial idea: Get rid of the XAML Image tag

Here's an idea I've had swimming around in the back of my brain for a while. I've not yet settled on it 100% yet, but when I do, I'll start some proposals, and discussions with the appropriate people/organizations/repositories.

This is me writing down my ideas to help better think them through and for those of you who come across this page to have a chance to share your thoughts.

Let's get rid of the <Image /> tag!

I acknowledge that this is a potentially controversial idea and it would be a BIG change to a lot of people but I think it has the possibility to advance XAML based development in two important areas: semantics and accessibility.

I'm increasingly persuading myself on the benefits of improving the intent of written XAML. Having a generic image tag only communicates that an image should be displayed but provides no information about how that image is used within the UI. This is far from optimal. Alternative/replacement controls could do a better job of communicating intent and aiding the readability of the code.

The vast majority of XAML based apps that I've seen make little or no regard for accessibility support and how screen-readers work with images in apps created with XAML. While HTML and the web are far from perfect, they do a much better job of encouraging people to use "alt" tags on their images. As accessibility and inclusive design continue to grow in importance and consideration for all users of all software, I expect an increased need for XAML based UIs to be asked to do a better job in the coming years.

How would we get rid of it?
In an ideal world, I'd mark it deprecated and then rename it (to BaseIamge) and make it abstract. I'd then add tooling to indicate it shouldn't be used and a suitable replacement is used instead.
The tooling part is easy (:wink:) but the other parts would cause A LOT of compatibility issues. I'd settle for introducing alternatives and recommending they are used instead. I don't really expect to be able to change the current Image tag.

What I propose we have instead

I propose adding two new controls to replace (or be used instead of) the current one: BackgroundImage and ContentImage.

This would support an image source and be almost identical to the current Image control. The difference would be that this would never show up in accessibility tools. It's just a background, so it doesn't matter if some users of the software don't know about it. The name also communicates to future developers that this is just part of the background and shouldn't host anything important like the content.

This would be like the existing Image control but also add a required description property. The value assigned to this property would be made available to accessibility tools so that anyone using the app but unable to view the image wouldn't miss out on important content information.
The description could also be used as a fallback if the image couldn't be used, similar to how alt text is displayed on websites when images don't load.
Tooling could easily be added to check that this property is set and a suitable (non-empty) value is provided.

I might have missed something obvious but I think almost all uses of images in apps could be classified as background or content.

That's it. It's quite simple.

  • Stop using Image.
  • Use BackgroundImage for visuals that aren't important and only part of the visual aspect of the page.
  • Use ContentImage for pictures that do contain important information that should be communicated to the user even if they aren't able to view the image.

As this is the internet, feel free to tell me why I'm wrong, what a silly idea this is, and the obvious things I've overlooked. ;)

Monday, March 16, 2020

Introducing: Clearly Editable - making it clear which documents can be edited in Visual Studio

The way some people* use Visual Studio means that they may use or open generated or read-only documents.

There can be lots of reasons for this:

  • They might generate code with a tool.
  • They may need to debug the compiler-generated code.
  • They might use a version control tool that locks files by making them read-only.
  • Many other, valid, reasons...

When working with such files, it can be REALLY frustrating when:

  • you start typing in a document but nothing happens (because it's read-only.) or
  • you make some changes in a generated document (because you don't realize it's generated) and those changes are lost when the file is regenerated.

Visual Studio already has some ways to try and help avoid the above scenarios but they're not always enough.

When a read-only file is open this icon is shown in the tab.
But it's small and easy to miss.

Generated documents typically have a comment in the header of the document to point out that it's been generated and should not be edited directly.
// <auto-generated>
//     This code was generated by a tool.
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// </auto-generated>
But, comments aren't always read, or even visible. It can also be easy to forget that a document is generated when switching between documents or if it's been open for a long time.

I present an alternative solution.

It changes the background color of the editor to make it harder to forget or miss if a file is read-only or generated.

The image below shows three open documents.

  • The document on the left is a generated file and has the background set to a pale green color.
  • The middle document is a read-only file and has the background set to a pale red color.
  • The document on the right is neither generated or read-only, just like most files you work with and so there are no modifications to the configured theme colors.

The intention here is that different background colors are harder to miss.

The colors are configurable.

Change them to what you prefer and what works with your other theme/color settings.

You can set the color by specifying a color name or an RGB HEX code.
Opacity is set by providing a percentage so that is can work with named colors and because calculating RGBA (or ARGB) isn't the simplest thing in the world for everyone.
You can also disable the highlighting of either type of file. Or, disable all functionality without having to uninstall the extension and restart Visual Studio.

Go to Tools > Options > Clearly Editable

Options dialog showing the default settings.

Give it a try by installing it from the Visual Studio Marketplace.
If you like it, please leave a review.
If you encounter any problems or have suggestions, please open an issue on GitHub.

* If this isn't you, that's fine. I have other extensions that might be useful to you.

VB.NET is done, not dead

This post on Visual Basic support planned for .NET 5.0 has caused some to complain that Microsoft is abandoning or killing Visual Basic. Discussions on plans for alternatives or open-source continuations or extensions to the language have picked up.

In amongst all the hype, hyperbole, and over-reactions, it's important to take a step back and think about the big picture.

There are plans from Microsoft to continue to support Visual Basic going forward.

  • If you use Visual Basic to build software based on the .NET Framework that will continue to work and be supported.
  • If you use (or want to use) Visual Basic to build software based on .NET Core (& .NET 5 going forward) that will work and be supported. And, as per that blog post, more application types will be supported than are currently.

There are plans to stop evolving the language and adding new features.

  • Adding new features makes it hard for people new to a language to learn it as there is more to learn. Visual Basic has always focused on making it easy to get started.
  • Every language doesn't need every feature. 
  • It's ok to use more than one language. No, you can't use them in the same project, but you can use them in different projects in the same solution.
  • This may mean that there is future functionality added to .NET Core that isn't as easy to use in Visual Basic. I'm sure workarounds and alternatives will be found though. A similar impact has also been had on C# where there are C#8.0 features that can't be used in software based on .NET Framework. At least VB developers will be spared the "what features of the language can I use in this code-base?" question.
  • Trust that Microsoft isn't making this decision to be difficult or pick on people who like using Visual Basic. Assume this is a business decision based on lots of data and discussion with the understanding of the consequences of doing this, as well as the benefits that can be gained by focusing efforts elsewhere.

If all you know is Visual Basic and you worry your skills are becoming less relevant, don't panic.
Learning new programming languages can be easier than you might imagine and typically brings insights into how you may want to use the language(s) you already use.

Also know that you know more than just a programming language.

  • You know how to put software together.
  • You know what good and bad coding practices look like.
  • You know how to work with other developers and other people in a business to deliver a software product.
  • You know how to solve problems when code doesn't do what you want.
  • You know how to ask and look for help.
  • You know what people using your software do and don't want.
  • You know much more than just a programming language.

Of course, things may change. But this is the world of technology. New things are created, adoption and usage changes, and older things are used less. Software is a world of constant change. If that's something you can't cope with it might not be for you.

And remember:

Wednesday, February 12, 2020

Resource Pseudo Localization - Protecting developers from themselves

I have a tool to help test the localization of strings in an app. It does this by making changes to the resource files (.resx & .resw) to help make it easy to test that all content is coming from the resource file. There are a number of different options available and more on this is covered in my book.

I've just released a new version (3.0) that adds a single new feature.

The new feature is that it creates a backup of the original file before it changes the content.

I know that it can be frustrating when tools create unnecessary extra files but I feel this is better than someone getting into a situation where they lose lots of work.

There's an option to turn this off if it's not wanted but it's on by default as that's better for avoiding unexpected negative consequences.

This isn't the result of someone having a problem. Rather, it's me trying to avoid a problem before it occurs.
Someone did ask how to get back after they'd toggled one of the options (you just need to toggle it again to undo the change) but I realized that not everything is obvious to everyone and there are all sorts of developers with various skills, knowledge, and experience.
In case anyone ever converts all their resources to something that can be automatically reversed, and they don't have another copy, and they don't have source control. At least they'll now have a backup.

If you're interested in trying out this extension, you can get it from the VS Marketplace.

Monday, February 10, 2020

Modern XAML Development - slides and overview

Slides! - because that's all some people think a talk is.

Let me add some background.

Above are a modified version of the slides used in this talk. The modifications remove things that aren't relevant, were there just as a backup for the more risky demos, and strip out the animations.

This is not the whole talk!
There is no way you could take this deck and give the same talk.
For starters, there are 10 (yes ten) demos that aren't included here.

I do not have slide notes.
Sorry, no. For what the slide doesn't make clear you're out of luck.

It's a talk, and the slides are there to support what I say. I'm not there to talk about the text on the screen. I know some people do it that way but I don't.

The basic structure of the talk is as follows:
  • Why XAML was created?
  • How it's developed and evolved.
  • XAML has multiple versions, allows you to build for multiple platforms, and has multiple ways of doing things.
  • Given all those variations, tooling hasn't always been great, but that is starting to change.
  • There is a lot to be gained when thinking about XAML as code and what you expect from the tooling for other languages.
  • Given that comparison:
    - What about creating apps that use XAML?
    - What can be done in the editor?
    - What can be done in the designer?
    - What can be done at run-time?
  • What's coming in the future?
  • Conclusion and questions
I don't have a script for the whole talk. That's why I can't share one here.
Instead, I plan by focusing on the overall structure. I then look at how different elements can fit into that structure.

The structure comes down to two parts.

  1. Provide background
  2. Walkthrough building an app and show how the tooling can help at different stages.

Within the walkthrough, I combine a number of small demos to show different features and that things work with different platforms. This means jumping between WPF, UWP, and Xamarin.Forms projects but this shows that the tools apply regardless of the platform without repeating everything three times or just claiming what's possible.
Having multiple small demos also allows me to focus on one thing in each demo. Trying to put everything in a single demo was more complicated than I could manage and involved too many things being on screen at once which was potentially distracting and confusing.
Having multiple small demos made them easy to practice. I practiced the demos many many times in preparation for giving the talk. Having small, simple demos allows me to experiment within the rehearsal to become familiar with variations. It allowed me to explore things like "what if I did this differently?", "How could this go wrong?", or "How could I make this simpler?".
Because each demo doesn't depend (much) on what's gone before it I can make changes in one demo without having to worry about possible negative consequences in subsequent demos.
Finding times to practice small demos is easier for me to do than finding the time to practice a long, complicated demo.
Not being tied to a specific, strict format allows me the flexibility to adjust the talk when given based on anything that may happen on the day, has been said in other talks earlier in the conference, or where my mind goes at the time.

Preparing this way takes ages. It's not something that can be done without a lot of time to prepare and so it's not a technique that can always be used. I do it where/when I can.

I made sure to know the content inside out and roughly how long each section takes and then adjusted what I said accordingly on the day.

I deliberately include some questions on slides at the end. This is for a number of reasons.
  • It shows I'm open to answering difficult questions.
  • It provides an easy way to answer common questions that I didn't cover earlier.
  • It provides an opportunity to cover questions that don't naturally fit into the rest of the talk.

When I gave this talk in Stokholm I finished, including the Q&A section with 3 seconds remaining.
Additional questions were taken 1-to-1 immediately after the talk.

Hopefully, this is useful if you're interested.

Also, links to tools mentioned in the talk can be found at

Tuesday, February 04, 2020

Modern XAML Development - notes from SWETUGG

Today (at the time of posting) I'm talking in Stokholm about Modern XAML Development.

Here for your simple consumption are links to all the things I talked about, demonstrated or otherwise mentioned.

Sorry, it's not the actual slides. There are only so many cat pictures I want to contribute to the web. ;)

Slides and notes can be found at

Friday, January 24, 2020

Feb 25th is UnoPlatform day (in London & Birmingham)

Are you in London or Birmingham (in the UK)?
Want to learn more about the Uno platform?

Uno logo

You're in luck, as I'm giving introductory talks:

In London, on the morning of Feb 25, at 9AM

In Birmingham, on the evening of Feb 25, at 6PM

More details and registration can be found by following the above links.

If you're in (or near) London but can't attend at this time (maybe you have work or something like that) stay tuned for details of an evening event coming soon...

Thursday, January 23, 2020

Usability Matters for the Surface Neo and the Surface Duo

Concept images of Surface Neo and Surfsce Duo devices

In my book (Usability Matters), I cover details about identifying reasons for building apps and planning app development.

Before the new surface devices arrive and trying to avoid the hype, in this post, I want to use the structure and pointers from the book to highlight important areas about which to think.

Assuming you have an existing app and are thinking about adjusting it for these new devices.

Are these devices going to be available where your users are?
These devices are unlikely to be available globally when launched, or even in a few months after. Using the launch of previous Surface devices as a guide, expect them in North America and parts of Western Europe first. If that's not where your users are, then you may be able to wait and learn from the real experiences of others before needing to do work yourself.

Are your users likely to get these devices?
I don't know anyone who reasonably expects these devices to be cheap. They're new, cutting edge devices pushing the boundaries. Such devices aren't something that usually comes cheap. Other Surface devices do not have price tags that make them accessible to everyone. It's tough for device manufacturers to make money from selling devices*, and this also points to an expected higher price point.
If your users aren't already using high-end devices, it's unlikely that they'll start using these devices (or similar) as soon as they're released.

* As an aside, I heard recently of a manufacturer planning to leave the handset business as it is so hard for them to make money.

Will the devices provide opportunities appropriate for your app and users?
At the moment, it's hard to know. What will happen when "real people" get to use these devices? Will they use them in the ways you or Microsoft expect? You will need to research to find this out. While this may not be possible for you yet, what you can do is make sure you understand what your current users are doing. To do so will require adding usage analytics into your app if you don't have them already. 

What is your goal in attempting to understand and develop for these devices?
  • Is it curiosity?
  • Are you a Microsoft fan who is only interested as this is something they're doing?
  • Do you aim to ensure an adequate experience when someone uses your app on such devices?
  • Do you hope to take advantage of the unique opportunities the new form factors will provide in terms of ways of working or using a device?
  • Or, are you looking for a possible boost from being one of a (potentially) small number of apps specifically built or updated to work with these new devices upon their launch?
If you understand your motivation, you'll be able to work towards achieving the related goals. It'll also help you avoid setting inappropriate goals or retrospectively thinking you were setting yourself up for a different possible outcome.

What can you learn from other, existing, two-screen devices?
While there will be differences between the Surface devices and what's currently on the market, there are lessons that can be learned from the similarities or otherwise.

How might you need to think about redesigning different screens for larger sizes?
Do you need to think about dynamic layouts, different orientations, or assets of different sizes?
Will you need to make any changes to your existing logic regarding assumptions about devices based on screen sizes, the number of screens, or device input?

Have you thought about your expectations?
Document your expectations. Then you can act accordingly. Check how they reflect reality or need adjusting as more information comes out.

How are you planning for these new devices and being ready for them?
Set aside times and monitor timelines to learn about, research, and experiment with them. Think about how SDKs, tools, emulators, controls, design concepts, device specs, and announcements about distribution and availability.

Tuesday, January 21, 2020

What I learned about PowerApps at #MSIgniteTheTour (London)

Lots of people who self-identify as "developers" (rather than "IT Pros") attend Ignite The Tour, but the focus of the event is more on the world of the IT Pro.

I see myself as a developer more than an IT Pro but attended anyway. With no sessions immediately applicable to my day-to-day work(?), I went to learn something new. Specifically, I wanted to learn about PowerApps.

(Yes, my recent post about Citizen Development is related to this.)

The existing knowledge I took with me was this:
  • I've used and evaluated many "no-code" tools over my career and am familiar with the concept and some common issues.
  • I was excited by the idea of PowerApps when it was announced (several years ago) but never find the time to learn more.
  • Apart from watching a few introductory sessions from an online PowerApps conference a few years ago, that reinforced some of my concerns.

I approached this as a complete beginner with a vague understanding of what it is and a healthy skepticism.

Here, in no particular order, is what I've learned.

  • It's not just one thing. PowerApps is part of the "Power Platform." Power Automate (recently renamed from Flow) is closely connected with PowerApps, and it's common to use both. There's also Power BI as part of the power family and is for analytics and data visualization.
  • If you talk to people focused on Power Platform, they'll say it has a lot in common with Dynamics. The "Dynamics people" I spoke to said they're very different.
  • All data access is through the Common Data Service. The CDS is a gateway to all information inside an enterprise (and is also used by the Dynamic family), plus it has connectors to other data sources and actions.
  • They're all very focused on the enterprise.
  • There are three types of Power App: Model-Driven, Canvas, and Portals.
  • Model-Driven apps are suitable for admin tasks and make elementary forms over data solutions possible.
  • Canvas apps (so-called as you start with a "blank canvas") let you do anything(?) and are what you build for distribution to people within your organization.
  • Portal apps are what you make for people outside your organization. Useful for simple websites or kiosk-style displays within company premises.
  • All types of PowerApp can run in a browser or a host app.
  • There's a new thing called AI builder. It's a simple way to introduce AI (based on simple ML models) into Power Apps (and automations.)
  • The knowledge needed to build custom apps is apparently equivalent to that required to create Excel macros.
  • There are a lot of built-in functions available in Power Apps. Apparently, 50% of them are from Excel, and the other 50% "are things you'll never need." - I'm very suspicious of this claim.
  • The cost of licensing of PowerApps is something over which lots of people have concerns (complaints?). I haven't looked at this yet, but it's something to be aware of.
  • Custom components can be created in Visual Studio Code with the PowerApps Component Framework.
  • Other developer-related tools are CLI based.
  • Authorization and governance to create, distribute, and use PowerApps are built into the platform. 
  • As I expected, apparently, "it's very easy to write a bad canvas app."
  • The accessibility of created PowerApps isn't always great but something that is being worked on.
  • There is some level of app diagnostics built-in.
  • There is a custom framework for testing PowerApps, but it's relatively new.
  • There's a new "solution checker" coming soon that will highlight possible issues in an app.
  • There appears to be minimal support for common mobile scenarios like occasional connectivity.
  • The Common Data Service provides a way to centralize authentication, access management, and business logic. When someone from the audience asked how to take advantage of those things in an app built separately (i.e., not a Power App), the answer from the stage was to rewrite it as a PowerApp. That's the wrong answer. Wrong in that it's unacceptable. It doesn't appreciate the realities of many business and development environments.
  • I'm unconvinced it's as easy and straight forward to use as many people claim. Of the many demos I watched (given by Microsoft staff and industry experts--MVPs), even though they were doing simple tasks, they frequently chose the wrong options or switched to pre-prepared items to use as part of a solution.

This isn't the end.
I now know where to go to learn more and try it out for myself.
Apparently, anyone can try a demo version at, and there are excellent resources on Microsoft Learn.

When I find the time to go further, I'll share more of my experiences here.

String Resource Visualizer - v 1.5

Sometimes it can be useful to think about lots of different solutions to a problem before picking the one to implement.
Other times you know just the right thing to do straight away.

A request came in for String Resource Visualizer to add support for a language other than the default.

Here's a screenshot of the current version in action.

This is all good and useful, but the request is to help developers whose first or preferred language isn't the same as the default culture for the app's code.

This is a request I wanted the tool to be able to support so I started to think about the different ways to implement this.

Then I stopped.
There's one key thing to define: the language to use in preference to the default.
Secondarily it might be possible to have rules about which languages to use for which solution, or order of preferred languages, and possibly other configurable options.

Rather than make things unnecessarily complicated I chose to use the existing system for handling settings. I then chose to make the change as simple as possible. Opting to only support a single configurable option with reasonable fallback options as there's no point in creating more complex functionality until it's wanted.

I've been thinking a lot about not just jumping to the first solution that comes to mind and trying to look at multiple possible solutions to find what's best. It's just that this didn't seem like the right opportunity to explore this. Some times the first solution is good enough. Especially, when following existing patterns.

As of the just-released, version 1.5, there's now a way to also see the resources for a language/culture that isn't the default.

Options page for specifying the preferred culture

This will cause resources in the specified language to be shown when they exist. The default is then used as a fallback.
Hopefully, this image provides a good example of this in action.

The new version is available in the marketplace now.
If you're an existing user and don't need this functionality you may still benefit from updating as there are also performance improvements in this new version.

Thursday, January 16, 2020

Rapid XAML - sticking with the name

Back in November last year, while awaiting the transfer of ownership, I considered renaming the Rapid XAML Toolkit.

Spoiler, I decided to keep it the same.

However, possible pronunciation issues almost made me reconsider.

It's a hard word for some to pronounce.

It can be confused for rabid or rabbit (🐇). I've even heard some people pronounce "wrapped" the way I pronounce 'rapid.'

To complicate things further, today, I also saw this.

I'm still sticking put though.
Hopefully, I'll be able to promote it in a way that can avoid confusion over the name and its pronunciation.

Friday, January 10, 2020

4 responses to Citizen Development

I was recently asked what I thought about citizen developers/development.
If you're not familiar with the term, it's the ability for "power-users" to create apps for their own use.

My answer comes in four parts.
  1. In General
  2. As a developer
  3. As a business-person
  4. and as a designer.

General (human response)
Citizen development is a good thing. It's great to be able to empower people to create their own solutions and not have them be held back through limited resources or overly controlling processes.


Developer (and IT department)
With my "developer hat" on I have some concerns.
- Will developers in the company be expected to support such apps?
- Will developers be asked to change citizen developed apps?
- How will these apps work alongside other developed software?
- Will the same rigors of testing and reliability be applied to citizen developed apps as ones created by an IT department?
- What if a citizen developed app needs to be reimplemented by the IT department? Is this something that needs to be considered, planned, or prepared for?
- How to balance the needs of an entire company when some departments are doing citizen development and others aren't?
- How to avoid the creation of a "shadow IT" department? Or departments going out and doing other IT related things themselves?
- What support is needed/required from the IT department for those creating citizen apps?

With my "business hat" on I have different concerns.
- How do we verify the accuracy of what's developed and what it does?
- What if there are legal consequences associated with actions taken in the apps? (e.g. personal or private information not tracked or protected correctly.)
- How do we keep track of what's developed, where they're distributed, when, where, and how they're used?
- What happens if the people who develop these things leave the company and changes need to be made?
- What happens if the company supplying the tools to make these apps goes away, or stops making them?
- What if we need a change or support from the company making the tool to create the apps?

These business and developer concerns may seem extreme but the idea of a department in a business that has their own Excel spreadsheet containing complex formulas and macros is common. That those spreadsheets are things that no-one knows all the details about how they work, what they actually do, how to successfully modify them, or the full consequences of changing them, is not uncommon. I see a great potential similarity between such spreadsheets and citizen developed apps.

With my "Designer-hat" on my concerns are different again.
- Most of the apps I've seen developed with these tools are ugly. At best they're like 20-year old WinForms apps. Through their crude visual designers, it's easy to end up with the app equivalent of bad PowerPoint and they don't have the tools or guidance to make anything better.
- There are more practical implications too. What about the accessibility needs of users of developed apps? How do they support accessibility tools like screen-readers? What about system-wide accessibility settings like text size changes or high-contrast?
- How are (or can) designers (be) involved in the creation of these apps to ensure good usability and UX practices?


So what can be done about this?
I'm not sure yet. I don't even know if these concerns are valid. They may not apply or matter to the businesses that use them.

I'm hoping that I'll learn more and get responses to some of my concerns when I attend Ignite: The Tour next week.

Tuesday, January 07, 2020

Decoding feedback - 4/5 stars

I recently saw this software review being shared on Twitter.
THIS APP HAS EVERYTHING I COULD WANT but it does more than I need. 4/5 stars
The implication was that if it does everything that they want the reviewer should have given it 5 stars.
4 filled stars, one empty
This sat in my mind for a while and the response I was building became too long for Twitter so I'm posting it here.

Part of the job of a developer and any business owner is to understand what customers (or users) want. Often you have to try and work this out for yourself. If you're fortunate they'll tell you what they think or what they think they want. The trick of being a good business owner, or product manager, or customer relations person, or developer working from a spec is being able to take what is said and working out what is meant.

Reviews are great feedback. Let's see what the person who left the above review might be telling us. With no more context, we have to guess at some of it but let's what they might be saying as an exercise in trying to understand the user and identify ways of improving a product.

  • This app does all they want. It's important to recognize that we're in a positive place and we want to make it even better. Don't start by being defensive and critical of what is mostly positive feedback. This is a learning opportunity.
  • But they don't think it's perfect. The opportunity for improvement.
  • Doing more than they need may be a problem. The challenge here is finding out why this is the case.
  • Maybe there are so many features, options, and pieces of functionality it's hard to get to the ones they want.
  • Maybe the features they want are at the bottom of or hidden in, a long list that the person has to search through each time.
  • Maybe the terms the app uses aren't the ones the person uses and so they are forced to remember (or figure out--through trial and error) the translations each time they use the app.
  • Maybe it's hard to do the things that they want, even though they are possible.
  • Maybe they have to navigate through multiple pages/sections/menus to get to the functionality they want.
  • Maybe the app has ways around the issue they're encountering but they don't know how and so it's just an education issue.

So, what could be done about this?

  • If possible, seek clarification.
  • Consolidate this feedback with what others are saying.
  • Address the concerns once it's known what they are.
    My guess is that the ability to mark options as favorites or maintain a recently used list will help but it's worth exploring the possible other issues highlighted above to see if they're issues too.


Sunday, January 05, 2020

The specified ITextSnapshot doesn't belong to the correct TextBuffer - a solution

I'm assuming you're reading this because you encountered this error message in a Visual Studio log and didn't know what to do about it.

"The specified ITextSnapshot doesn't belong to the correct TextBuffer."

You may even have found a number of other blog and forum posts looking for answers but finding none.
I've been there myself.

This is a record of how I fixed this issue. This applies to how I addressed it in an extension I'm writing. If you're just using VS and not writing an extension yourself this is unlikely to be useful or interesting. If you are investigating this because of an extension you're writing, please note that you might be having this issue because of another issue to me.

Disclaimer over, I noticed this error occurring when a config file was deleted from the project.

The call stack in the log wasn't immediately helpful either.

System.ArgumentException: The specified ITextSnapshot doesn&apos;t belong to the correct TextBuffer.&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.SnapshotSpan.TranslateTo(ITextSnapshot targetSnapshot, SpanTrackingMode spanTrackingMode)&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.&lt;GetTagsForBuffer&gt;d__47.MoveNext()&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.&lt;InternalGetTags&gt;d__51.MoveNext()&#x000D;&#x000A;   at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.GetNormalizedSquiggleSpanCollections(ITextViewLine line)&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.UpdateVisualsOn(IEnumerable`1 lines, Boolean removeOldSquiggles)&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.UpdateSquigglesOnInvalidatedSpans()&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.OnLayoutChanged(Object sender, TextViewLayoutChangedEventArgs e)&#x000D;&#x000A;   at Microsoft.VisualStudio.Text.Utilities.GuardedOperations.RaiseEvent[TArgs](Object sender, EventHandler`1 eventHandlers, TArgs args)

However, on reflection, it did provide a hint.
The mention of `GetTagsForBuffer` made me look at what I was doing with tagging.

In my `ITagger<T>` implementation I was using a cache of created tags to avoid needing to recreate them unnecessarily. However, it seems that changing the project that an open file is in causes a new TextBuffer to be created.
The consequence of this is that my cached tags now refer to a Snapshot with a different TextBuffer and that causes VS to have (but log) an exception.

My solution is that in the GetTags method, I check that the TextBuffer of the NormalizedSnapshotSpanCollection matches the TextBuffer of the SnapShot of the cached tags.
I only return the tags if they do match and if they don't I invalidate the cache for that file.

Hopefully, this helps save someone else some time trying to debug a similar issue.