Are you in London or Birmingham (in the UK)?
Want to learn more about the Uno platform?
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...
Friday, January 24, 2020
Thursday, January 23, 2020
Usability Matters for the Surface Neo and the Surface Duo
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 https://powerapps.microsoft.com/, 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.
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.
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.
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.
Any suggestions for an alternative name for 'Rapid XAML Toolkit'?— Matt Lacey (@mrlacey) November 26, 2019
(For clarity, it's a collection of tools for making it faster and easier to work with XAML)
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.
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.
However...
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?
Business-person
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.
Designer
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.
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.
- In General
- As a developer
- As a business-person
- 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.
However...
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?
Business-person
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.
Designer
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 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.
So, what could be done about this?
HT
THIS APP HAS EVERYTHING I COULD WANT but it does more than I need. 4/5 starsThe implication was that if it does everything that they want the reviewer should have given it 5 stars.
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.
HT
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.
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't belong to the correct TextBuffer.
 at Microsoft.VisualStudio.Text.SnapshotSpan.TranslateTo(ITextSnapshot targetSnapshot, SpanTrackingMode spanTrackingMode)
 at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.<GetTagsForBuffer>d__47.MoveNext()
 at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.<InternalGetTags>d__51.MoveNext()
 at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
 at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.GetNormalizedSquiggleSpanCollections(ITextViewLine line)
 at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.UpdateVisualsOn(IEnumerable`1 lines, Boolean removeOldSquiggles)
 at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.UpdateSquigglesOnInvalidatedSpans()
 at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.OnLayoutChanged(Object sender, TextViewLayoutChangedEventArgs e)
 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.
"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't belong to the correct TextBuffer.
 at Microsoft.VisualStudio.Text.SnapshotSpan.TranslateTo(ITextSnapshot targetSnapshot, SpanTrackingMode spanTrackingMode)
 at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.<GetTagsForBuffer>d__47.MoveNext()
 at Microsoft.VisualStudio.Text.Tagging.Implementation.TagAggregator`1.<InternalGetTags>d__51.MoveNext()
 at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
 at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.GetNormalizedSquiggleSpanCollections(ITextViewLine line)
 at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.UpdateVisualsOn(IEnumerable`1 lines, Boolean removeOldSquiggles)
 at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.UpdateSquigglesOnInvalidatedSpans()
 at Microsoft.VisualStudio.Text.AdornmentLibrary.Squiggles.Implementation.SquiggleVisualManager.OnLayoutChanged(Object sender, TextViewLayoutChangedEventArgs e)
 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.