The survey measure your overall satisfaction with the tool and the catalog of libraries. It also captures your needs and feedback to prepare the next version. Your input is essential for us to build a tool you need and use, thanks in advance for your time and inputs.
As always don’t hesitate to contact us for any issues or suggestions, you can open an issue on github or reach us at vcpkg@microsoft.com
Many developers use the Bing Maps REST services to perform spatial queries such as geocoding an address or calculating routes and distances. The Bing Maps REST services are nice and fast, however, using them from a .NET application used to require a decent amount of work. The Bing Maps .NET REST Toolkit aims to make it easy to use these services from your .NET application by providing a portable class library, which wraps the Bing Maps REST services and implements best practices to ensure the good performance and the most accurate results are returned. In the past, it could easily take an hour or more to add the Bing Maps REST services to their application. Now, with the aid of a NuGet package, you can implement the Bing Maps REST services in minutes. You can find this project on GitHub here.
How to use the .NET REST Toolkit
Add the REST Toolkit to your project
In Visual Studio, open the NuGet Package Manager, select the Browse tab and search for "Bing Maps REST". This will reduce the list of results enough to find the "BingMapsRESTToolkit" package. If you want to verify that you have the correct package, the listed owner of the package is bingmaps and the author is Microsoft. Install the package into your project.
Alternatively, if you are using the NuGet command line:
PM> Install-Package BingMapsRESTToolkit
Call the Bing Maps REST services using the Toolkit
The Bing Maps REST Toolkit has two key components, a service manager and a set of request classes. The ServiceManager is a static class that makes it easy to asynchronously process any Bing Maps REST request. Here is a list of the different requests classes available:
ElevationRequest
GeocodeRequest
ImageryMetadataRequest
ImageryRequest
ReverseGeocodeRequest
RouteMajorRoadsRequest
RouteRequest
TrafficRequest
The ServiceManager class has two static methods: GetResponseAsync and GetImageAsync. The GetResponseAsync method will return a Response object from the Bing Maps REST services which aligns with the documented Response object for the REST services. The GetImageAsync method will return a stream containing the image data.
The following is an example of how to make a geocode request and get the response from the Bing Maps REST services.
//Create a request.
var request = new GeocodeRequest()
{ Query = "New York, NY", IncludeIso2 = true, IncludeNeighborhood = true, MaxResults = 25, BingMapsKey = "YOUR_BING_MAPS_KEY"
};
//Process the request by using the ServiceManager.
var response = await ServiceManager.GetResponseAsync(request);
if(response != null && response.ResourceSets != null && response.ResourceSets.Length > 0 && response.ResourceSets[0].Resources != null && response.ResourceSets[0].Resources.Length > 0)
{ var result = response.ResourceSets[0].Resources[0] as BingMapsRESTToolkit.Location;
//Do something with the result.
}
The following is an example of how to request a map image from the Bing Maps REST services to retrieve the image stream.
//Create an image request.
var request = new ImageryRequest()
{ CenterPoint = new Coordinate(45, -110), ZoomLevel = 12, ImagerySet = ImageryType.AerialWithLabels, Pushpins = new List(){ new ImageryPushpin(){ Location = new Coordinate(45, -110.01), Label = "hi" }, new ImageryPushpin(){ Location = new Coordinate(45, -110.02), IconStyle = 3 }, new ImageryPushpin(){ Location = new Coordinate(45, -110.03), IconStyle = 20 }, new ImageryPushpin(){ Location = new Coordinate(45, -110.04), IconStyle = 24 } }, BingMapsKey = "YOUR_BING_MAPS_KEY"
};
//Process the request by using the ServiceManager.
using (var imageStream = await ServiceManager.GetImageAsync(request))
{ //Do something with the image stream.
//Here is how to display the image in an Image tag in a WPF app. var bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = imageStream; bitmapImage.EndInit(); MyImage.Source = bitmapImage;
}
Bing and Open Source
The Bing team has been working towards being more involved in the Open Source community. Here are a few other open source projects recently released by the Bing team that you may be interested in.
At the beginning of each new year, many people take on a challenge to learn something new or commit to reinforcing existing skills. Over the next two blogs posts, we will guide you through two amazing, free, developer training video series: C# fundamentals and UWP Development.
Both series require no prior programming experience, so they’re perfect for someone who wants to learn something new. However, since the videos span a wide array of topics, they’re also great to brush up on your existing skills.
The series are presented by Bob Tabor from Developer University (formerly learnvisualstudio.net). Bob is known for his easy-to- follow teaching style, keeping you engaged and entertained while learning the topic.
To get started, we’ll take a look at the first series: C# Fundamentals for the Absolute Beginner. In this free Microsoft Virtual Academy course, you will learn core C# concepts applicable to a wide range of classic and modern applications.
For the beginner, or if you’re coming from a different language, this series will walk you through getting the tools, writing code, debugging features, customizations and much more. For the experienced C# developer who wants to brush up on certain topics, each concept is explained in its own video so you can jump to a topic and focus on the information you want.
Microsoft Virtual Academy will keep track of your progress as you move through the modules and complete assessments. If you want to jump to a particular module, you can do that by clicking one of the links above or use the Contents tab next to the current video playing.
In the next post, we will take you through the next video course that will show you how to apply your new, or refreshed, C# skills and introduce you to XAML in a Windows 10 Universal Windows Application.
This release is big on Bluetooth. If you’re familiar with Windows Bluetooth APIs, have been meaning to try them out, or if you’re just starting to dabble in IoT and wearables, this is a great time to take a fresh look at all things Bluetooth. To ensure the APIs we built out are functional and performant, we are working directly with Fitbit, Garmin and other device manufacturers and we would love your feedback as well.
There are three main features in this month’s Insider preview:
GATT Server
Bluetooth LE Peripheral
Unpaired Bluetooth LE device connectivity
A lot of the improvements are focused on Bluetooth LE, but we have improved Bluetooth audio functionality as well. While we made a lot of changes under the hood to ensure that all your devices talk nicely with each other, we also added a couple of new features.
Call Control API support comes to desktop. This means your VoIP apps can natively take advantage of Bluetooth headset functionality like pick up, hang up, hold, call waiting, etc. You will also experience higher-quality audio for voice, thanks to Wideband speech– coming soon to desktop. Now, Cortana will sound more lifelike and your Skype sessions will sound better than ever over Bluetooth.
Now, let’s break down the LE portions of this feature set.
GATT Server
GATT (or Generic ATTribute) logically describes how data is structured and must function in a Bluetooth LE device. The device that has the interesting data is the Server, and the device that uses that data to perform a function is known as the Client. For example, a Windows Phone (Client) reads data from a heart rate monitor (Server) to track that a user is working out optimally. Windows has traditionally been a GATT Client but with the Windows 10 Creators Update, Windows can operate as the Server as well. The hierarchy of classes in the example heart rate service is described below, but you can pick and choose any logical set of characteristics and descriptors to make your custom GATT service.
Your phone or PC has notification/user credential information that a wearable device does not have. For instance, when an incoming text message comes in, Windows can act as the GATT Server and notify a nearby wearable of the text’s arrival. Diagram 1 shows a sample service structure using Bluetooth classes implemented in this release.
In addition to GATT roles which determine the structure of the data, Bluetooth defines Generic Access Profile (GAP) roles as well.
These GAP roles specify which device advertises as connectable and which device does the connecting. To connect a device, Windows users generally go to the Settings page, find the device they want to connect and tap to connect. This action of connecting to remote devices implies that Windows is operating in the GAP Central role. However, there are often cases where remote devices such as smart locks need to be aware of Windows, or where you’re trying to connect two Windows devices. In such cases, we need to make sure that Windows can advertise as connectable. With the new Insider preview, apps can put the system in a state to advertise support for Bluetooth LE services. With Peripheral role and GATT Server combined, Windows can operate in all four combinations of GATT and GAP roles (color choices arbitrary, of course):
Diagram 2: Windows operating in all GATT and GAP roles
Unpaired Bluetooth LE device connectivity
Traditionally, Bluetooth LE devices needed to be paired with Windows to be accessed. This either forced the user to switch context to the Settings page, or caused developers to implement in-app pairing logic within the app. Unfortunately, there were even devices that didn’t support pairing, which necessitated ugly workarounds for the developer. All that is going to change now with the new Async GATT APIs.
In the new APIs, take a look at BluetoothLEDevice.GetGattServicesAsync(), GattDeviceService.GetCharacteristicsAsync() as well as GattCharacteristic.GetDescriptorsAsync() to get an idea for how to query a remote device without pairing.
What you need to get started
It’s all in the release preview Build and SDK, available to download here. Once you install the build, take a look at the classes that were described in the previous sections and have at it. We’re a little light on the documentation right now, but we will remedy that soon.
Does this mean my can get notifications?
GATT Server will open up a myriad of Bluetooth LE device-to-device scenarios that we think are super exciting! Why limit yourself to “Notifications”? Think remote authentication, smart locks, proximity and IoT! The world is your (wireless) oyster. But yes, developers can start enabling notifications now. However, consumers will only see this functionality lit up once Windows 10 Creators Update is released and their updated app is in the store.
If you would like us to go deeper on any of the topics in this post, please let us know in the comment sections below.
In December, 2016 we announced the release of several new intelligence services for use with the Microsoft Bot Framework. Microsoft Cognitive Services QnA Maker, and the Bing Location Control were among those introduced. Both were created by the same engineers that work on Bing relevance, ranking, and the geo-spatial maps service. Below are a few details about each:
QnA Maker Service
The free preview of Microsoft Cognitive Services QnA Maker is an easy-to-use, REST API- and web-based service that trains AI to respond to users’ questions in a conversational way. QnA Maker works in three steps: extraction, training, and publishing. Bot Makers determine the source of their knowledge base content and, by extracting semi-structured data in the form of questions and answers in an FAQ document or webpage, the QnA Maker Service can create a knowledge base within a matter of minutes.
The open source Bing Location Control for Bot Framework allows bot developers to easily and reliably get the user’s desired location within a conversation using Bing Maps API. The control is available in C# and Node.js and works consistently across all messaging channels supported by Bot Framework. All this is done with a few lines of code.
Today, we released a new Windows 10 Creators Update SDK Preview to be used in conjunction with Windows 10 Insider Preview (Build 15003 or greater). The Preview SDK is a pre-release and cannot be used in a production environment. Please only install the SDK on your test machine. The Preview SDK Build 15003 contains bug fixes and under development changes to the API surface area. If you are working on an application that you need to submit to the store, you should not install the preview.
I cannot specify the new SDK version 15003 when creating a new project This version of the SDK only works with Visual Studio 2017. You can download the Visual Studio 2017 Preview. If you install the latest version Visual Studio 2017, you will be able to specify the build 15003.
API Updates and Additions:
The following API changes are under development and new or updated for this release of the SDK.
namespace Windows.ApplicationModel.Preview.Notes {
public sealed class NotesWindowManagerPreview {
void SetFocusToPreviousView();
IAsyncAction SetThumbnailImageForTaskSwitcherAsync(SoftwareBitmap bitmap);
void ShowNoteRelativeTo(int noteViewId, int anchorNoteViewId, NotesWindowManagerPreviewShowNoteOptions options);
void ShowNoteWithPlacement(int noteViewId, IBuffer data, NotesWindowManagerPreviewShowNoteOptions options);
}
public sealed class NotesWindowManagerPreviewShowNoteOptions
}
namespace Windows.Devices.Gpio {
public struct GpioChangeCount
public sealed class GpioChangeCounter : IClosable
public enum GpioChangePolarity
public sealed class GpioChangeReader : IClosable
public struct GpioChangeRecord
public enum GpioOpenStatus {
MuxingConflict = 3,
UnknownError = 4,
}
}
namespace Windows.Devices.I2c {
public enum I2cTransferStatus {
ClockStretchTimeout = 3,
UnknownError = 4,
}
}
namespace Windows.Devices.Pwm {
public sealed class PwmController {
public static IAsyncOperation FromIdAsync(string deviceId);
public static string GetDeviceSelector();
public static string GetDeviceSelector(string friendlyName);
}
}
namespace Windows.Devices.SmartCards {
public sealed class SmartCardTriggerDetails {
SmartCard SmartCard { get; }
}
}
namespace Windows.Devices.SmartCards {
public enum SmartCardCryptogramAlgorithm {
Sha256Hmac = 8,
}
public sealed class SmartCardCryptogramGenerator {
IAsyncOperation GetAllCryptogramMaterialCharacteristicsAsync(SmartCardUnlockPromptingBehavior promptingBehavior, string materialPackageName);
IAsyncOperation GetAllCryptogramMaterialPackageCharacteristicsAsync();
IAsyncOperation GetAllCryptogramMaterialPackageCharacteristicsAsync(string storageKeyName);
IAsyncOperation GetAllCryptogramStorageKeyCharacteristicsAsync();
IAsyncOperation ValidateRequestApduAsync(SmartCardUnlockPromptingBehavior promptingBehavior, IBuffer apduToValidate, IIterable cryptogramPlacementSteps);
}
public enum SmartCardCryptogramGeneratorOperationStatus {
ValidationFailed = 12,
}
public sealed class SmartCardCryptogramGetAllCryptogramMaterialCharacteristicsResult
public sealed class SmartCardCryptogramGetAllCryptogramMaterialPackageCharacteristicsResult
public sealed class SmartCardCryptogramGetAllCryptogramStorageKeyCharacteristicsResult
public sealed class SmartCardCryptogramMaterialCharacteristics
public sealed class SmartCardCryptogramMaterialPackageCharacteristics
public enum SmartCardCryptogramMaterialProtectionMethod
public sealed class SmartCardCryptogramStorageKeyCharacteristics
}
namespace Windows.Foundation.Metadata {
public sealed class FeatureAttribute : Attribute
public enum FeatureStage
}
namespace Windows.ApplicationModel {
public sealed class Package {
IAsyncOperation GetContentGroupAsync(string name);
IAsyncOperation> GetContentGroupsAsync();
IAsyncOperation SetInUseAsync(bool inUse);
IAsyncOperation> StageContentGroupsAsync(IIterable names);
IAsyncOperation> StageContentGroupsAsync(IIterable names, bool moveToHeadOfQueue);
}
public sealed class PackageCatalog {
event TypedEventHandler PackageContentGroupStaging;
IAsyncOperation AddOptionalPackageAsync(string optionalPackageFamilyName);
}
public sealed class PackageCatalogAddOptionalPackageResult
public sealed class PackageContentGroup
public sealed class PackageContentGroupStagingEventArgs
public enum PackageContentGroupState
public sealed class PackageStatus {
bool IsPartiallyStaged { get; }
}
}
namespace Windows.ApplicationModel.Activation {
public enum ActivationKind {
ContactPanel = 1017,
LockScreenComponent = 1016,
}
public sealed class ContactPanelActivatedEventArgs : IActivatedEventArgs, IActivatedEventArgsWithUser, IContactPanelActivatedEventArgs
public interface IContactPanelActivatedEventArgs
public sealed class LockScreenComponentActivatedEventArgs : IActivatedEventArgs
public sealed class ToastNotificationActivatedEventArgs : IActivatedEventArgs, IActivatedEventArgsWithUser, IApplicationViewActivatedEventArgs, IToastNotificationActivatedEventArgs {
int CurrentlyShownApplicationViewId { get; }
}
}
namespace Windows.ApplicationModel.Background {
public sealed class BackgroundTaskBuilder {
BackgroundTaskRegistrationGroup TaskGroup { get; set; }
}
public sealed class BackgroundTaskRegistration : IBackgroundTaskRegistration, IBackgroundTaskRegistration2, IBackgroundTaskRegistration3 {
public static IMapView AllTaskGroups { get; }
BackgroundTaskRegistrationGroup TaskGroup { get; }
public static BackgroundTaskRegistrationGroup GetTaskGroup(string groupId);
}
public sealed class BackgroundTaskRegistrationGroup
public sealed class GattCharacteristicNotificationTrigger : IBackgroundTrigger {
public GattCharacteristicNotificationTrigger(GattCharacteristic characteristic, BluetoothEventTriggeringMode eventTriggeringMode);
BluetoothEventTriggeringMode EventTriggeringMode { get; }
}
public sealed class GattServiceProviderTrigger : IBackgroundTrigger
public sealed class GattServiceProviderTriggerResult
public interface IBackgroundTaskRegistration3 : IBackgroundTaskRegistration
}
namespace Windows.ApplicationModel.Contacts {
public sealed class ContactAnnotation {
string ContactListId { get; set; }
}
public enum ContactAnnotationOperations : uint {
Share = (uint)32,
}
public sealed class ContactAnnotationStore {
IAsyncOperation> FindAnnotationsForContactListAsync(string contactListId);
}
public sealed class ContactGroup
public static class ContactManager {
public static bool IncludeMiddleNameInSystemDisplayAndSort { get; set; }
public static IAsyncOperation IsShowFullContactCardSupportedAsync();
}
public sealed class ContactManagerForUser {
void ShowFullContactCard(Contact contact, FullContactCardOptions fullContactCardOptions);
}
public sealed class ContactPanel
public sealed class ContactPanelClosingEventArgs
public sealed class ContactPanelLaunchFullAppRequestedEventArgs
public sealed class ContactPicker {
User User { get; }
public static ContactPicker CreateForUser(User user);
public static IAsyncOperation IsSupportedAsync();
}
public sealed class PinnedContactIdsQueryResult
public sealed class PinnedContactManager
public enum PinnedContactSurface
}
namespace Windows.ApplicationModel.Core {
public sealed class CoreApplicationView {
IPropertySet Properties { get; }
}
}
namespace Windows.ApplicationModel.DataTransfer {
public sealed class DataPackage {
event TypedEventHandler ShareCompleted;
}
public sealed class DataTransferManager {
event TypedEventHandler ShareProvidersRequested;
}
public sealed class ShareCompletedEventArgs
public sealed class SharePeople
public sealed class ShareProvider
public delegate void ShareProviderHandler(ShareProviderRequest request);
public sealed class ShareProviderRequest
public sealed class ShareProvidersRequestedEventArgs
public sealed class ShareTargetInfo
}
namespace Windows.ApplicationModel.DataTransfer.ShareTarget {
public sealed class ShareOperation {
SharePeople People { get; }
}
}
namespace Windows.ApplicationModel.Email {
public sealed class EmailMessage {
IVector ReplyTo { get; }
EmailRecipient SentRepresenting { get; set; }
}
}
namespace Windows.ApplicationModel.Payments {
public sealed class PaymentAddress
public sealed class PaymentCurrencyAmount
public sealed class PaymentDetails
public sealed class PaymentDetailsModifier
public sealed class PaymentItem
public sealed class PaymentMediator
public sealed class PaymentMerchantInfo
public sealed class PaymentMethodData
public enum PaymentOptionPresence
public sealed class PaymentOptions
public sealed class PaymentRequest
public sealed class PaymentRequestChangedArgs
public delegate void PaymentRequestChangedHandler(PaymentRequest paymentRequest, PaymentRequestChangedArgs args);
public sealed class PaymentRequestChangedResult
public enum PaymentRequestChangeKind
public enum PaymentRequestCompletionStatus
public enum PaymentRequestStatus
public sealed class PaymentRequestSubmitResult
public sealed class PaymentResponse
public sealed class PaymentShippingOption
public enum PaymentShippingType
public sealed class PaymentToken
}
namespace Windows.ApplicationModel.Payments.Provider {
public sealed class PaymentAppManager
public sealed class PaymentTransaction
public sealed class PaymentTransactionAcceptResult
}
namespace Windows.ApplicationModel.Preview.Holographic {
public static class HolographicApplicationPreview
}
namespace Windows.ApplicationModel.Store.LicenseManagement {
public static class LicenseManager {
public static IAsyncAction RefreshLicensesAsync(LicenseRefreshOption refreshOption);
}
public enum LicenseRefreshOption
}
namespace Windows.ApplicationModel.Store.Preview {
public static class StoreConfiguration {
public static string GetEnterpriseStoreWebAccountId();
public static string GetEnterpriseStoreWebAccountIdForUser(User user);
public static string GetStoreWebAccountId();
public static string GetStoreWebAccountIdForUser(User user);
public static void SetEnterpriseStoreWebAccountId(string webAccountId);
public static void SetEnterpriseStoreWebAccountIdForUser(User user, string webAccountId);
public static bool ShouldRestrictToEnterpriseStoreOnly();
public static bool ShouldRestrictToEnterpriseStoreOnlyForUser(User user);
}
}
namespace Windows.ApplicationModel.Store.Preview.InstallControl {
public sealed class AppInstallManager {
IAsyncOperation GetFreeDeviceEntitlementAsync(string storeId, string campaignId, string correlationVector);
IAsyncOperation GetFreeUserEntitlementAsync(string storeId, string campaignId, string correlationVector);
IAsyncOperation GetFreeUserEntitlementForUserAsync(User user, string storeId, string campaignId, string correlationVector);
}
public sealed class GetEntitlementResult
public enum GetEntitlementStatus
}
namespace Windows.ApplicationModel.UserActivities {
public sealed class UserActivity
public sealed class UserActivityChannel
public sealed class UserActivitySession : IClosable
public enum UserActivityState
public sealed class UserActivityVisualElements
}
namespace Windows.ApplicationModel.UserActivities.Core {
public static class CoreUserActivityManager
}
namespace Windows.ApplicationModel.UserDataAccounts {
public sealed class UserDataAccount {
bool CanShowCreateContactGroup { get; set; }
IRandomAccessStreamReference Icon { get; set; }
bool IsProtectedUnderLock { get; set; }
IPropertySet ProviderProperties { get; }
IAsyncOperation> FindContactGroupsAsync();
IAsyncOperation> FindUserDataTaskListsAsync();
IAsyncOperation TryShowCreateContactGroupAsync();
}
public sealed class UserDataAccountStore {
IAsyncOperation CreateAccountAsync(string userDisplayName, string packageRelativeAppId, string enterpriseId);
}
}
namespace Windows.ApplicationModel.UserDataTasks {
public sealed class UserDataTask
public sealed class UserDataTaskBatch
public enum UserDataTaskDaysOfWeek : uint
public enum UserDataTaskDetailsKind
public enum UserDataTaskKind
public sealed class UserDataTaskList
public sealed class UserDataTaskListLimitedWriteOperations
public enum UserDataTaskListOtherAppReadAccess
public enum UserDataTaskListOtherAppWriteAccess
public sealed class UserDataTaskListSyncManager
public enum UserDataTaskListSyncStatus
public sealed class UserDataTaskManager
public enum UserDataTaskPriority
public enum UserDataTaskQueryKind
public sealed class UserDataTaskQueryOptions
public enum UserDataTaskQuerySortProperty
public sealed class UserDataTaskReader
public sealed class UserDataTaskRecurrenceProperties
public enum UserDataTaskRecurrenceUnit
public sealed class UserDataTaskRegenerationProperties
public enum UserDataTaskRegenerationUnit
public enum UserDataTaskSensitivity
public sealed class UserDataTaskStore
public enum UserDataTaskStoreAccessType
public enum UserDataTaskWeekOfMonth
}
namespace Windows.ApplicationModel.UserDataTasks.DataProvider {
public sealed class UserDataTaskDataProviderConnection
public sealed class UserDataTaskDataProviderTriggerDetails
public sealed class UserDataTaskListCompleteTaskRequest
public sealed class UserDataTaskListCompleteTaskRequestEventArgs
public sealed class UserDataTaskListCreateOrUpdateTaskRequest
public sealed class UserDataTaskListCreateOrUpdateTaskRequestEventArgs
public sealed class UserDataTaskListDeleteTaskRequest
public sealed class UserDataTaskListDeleteTaskRequestEventArgs
public sealed class UserDataTaskListSkipOccurrenceRequest
public sealed class UserDataTaskListSkipOccurrenceRequestEventArgs
public sealed class UserDataTaskListSyncManagerSyncRequest
public sealed class UserDataTaskListSyncManagerSyncRequestEventArgs
}
namespace Windows.Devices.Bluetooth {
public sealed class BluetoothAdapter
public enum BluetoothAddressType {
Unspecified = 2,
}
public sealed class BluetoothDeviceId
public enum BluetoothError {
TransportNotSupported = 9,
}
public sealed class BluetoothLEDevice : IClosable {
DeviceAccessInformation DeviceAccessInformation { get; }
IAsyncOperation GetGattServicesAsync();
IAsyncOperation GetGattServicesAsync(BluetoothCacheMode cacheMode);
IAsyncOperation GetGattServicesForUuidAsync(GattUuid serviceUuid);
IAsyncOperation GetGattServicesForUuidAsync(GattUuid serviceUuid, BluetoothCacheMode cacheMode);
IAsyncOperation RequestAccessAsync();
}
}
namespace Windows.Devices.Bluetooth.Background {
public enum BluetoothEventTriggeringMode
public sealed class GattCharacteristicNotificationTriggerDetails {
BluetoothError Error { get; }
BluetoothEventTriggeringMode EventTriggeringMode { get; }
IVectorView ValueChangedEvents { get; }
}
public sealed class GattServiceProviderConnection
public sealed class GattServiceProviderTriggerDetails
}
namespace Windows.Devices.Bluetooth.GenericAttributeProfile {
public sealed class GattCharacteristic {
IAsyncOperation GetDescriptorsAsync();
IAsyncOperation GetDescriptorsAsync(BluetoothCacheMode cacheMode);
IAsyncOperation GetDescriptorsForUuidAsync(GattUuid descriptorUuid);
IAsyncOperation GetDescriptorsForUuidAsync(GattUuid descriptorUuid, BluetoothCacheMode cacheMode);
IAsyncOperation WriteClientCharacteristicConfigurationDescriptorWithResultAsync(GattClientCharacteristicConfigurationDescriptorValue clientCharacteristicConfigurationDescriptorValue);
IAsyncOperation WriteValueWithResultAsync(IBuffer value);
IAsyncOperation WriteValueWithResultAsync(IBuffer value, GattWriteOption writeOption);
}
public sealed class GattCharacteristicsResult
public sealed class GattClientNotificationResult
public enum GattCommunicationStatus {
ProtocolError = 2,
}
public sealed class GattDescriptor {
IAsyncOperation WriteValueWithResultAsync(IBuffer value);
}
public sealed class GattDescriptorsResult
public sealed class GattDeviceService : IClosable {
DeviceAccessInformation DeviceAccessInformation { get; }
GattSession Session { get; }
GattSharingMode SharingMode { get; }
public static IAsyncOperation FromIdAsync(string deviceId, GattSharingMode sharingMode);
IAsyncOperation GetCharacteristicsAsync();
IAsyncOperation GetCharacteristicsAsync(BluetoothCacheMode cacheMode);
IAsyncOperation GetCharacteristicsForUuidAsync(GattUuid characteristicUuid);
IAsyncOperation GetCharacteristicsForUuidAsync(GattUuid characteristicUuid, BluetoothCacheMode cacheMode);
public static string GetDeviceSelector(GattUuid gattUuid);
public static string GetDeviceSelectorForBluetoothDeviceId(BluetoothDeviceId bluetoothDeviceId);
public static string GetDeviceSelectorForBluetoothDeviceId(BluetoothDeviceId bluetoothDeviceId, BluetoothCacheMode cacheMode);
public static string GetDeviceSelectorForBluetoothDeviceIdAndGattUuid(BluetoothDeviceId bluetoothDeviceId, GattUuid gattUuid);
public static string GetDeviceSelectorForBluetoothDeviceIdAndGattUuid(BluetoothDeviceId bluetoothDeviceId, GattUuid gattUuid, BluetoothCacheMode cacheMode);
IAsyncOperation GetIncludedServicesAsync();
IAsyncOperation GetIncludedServicesAsync(BluetoothCacheMode cacheMode);
IAsyncOperation GetIncludedServicesForUuidAsync(GattUuid serviceUuid);
IAsyncOperation GetIncludedServicesForUuidAsync(GattUuid serviceUuid, BluetoothCacheMode cacheMode);
IAsyncOperation OpenAsync(GattSharingMode sharingMode);
IAsyncOperation RequestAccessAsync();
}
public sealed class GattDeviceServicesResult
public sealed class GattLocalCharacteristic
public sealed class GattLocalCharacteristicParameters
public sealed class GattLocalCharacteristicResult
public sealed class GattLocalDescriptor
public sealed class GattLocalDescriptorParameters
public sealed class GattLocalDescriptorResult
public sealed class GattLocalService
public enum GattOpenStatus
public sealed class GattPresentationFormat {
public static GattPresentationFormat FromParts(byte formatType, int exponent, ushort unit, byte namespaceId, ushort description);
}
public static class GattProtocolError
public sealed class GattReadClientCharacteristicConfigurationDescriptorResult {
IReference ProtocolError { get; }
}
public sealed class GattReadRequest
public sealed class GattReadRequestedEventArgs
public sealed class GattReadResponse
public sealed class GattReadResult {
IReference ProtocolError { get; }
}
public sealed class GattReliableWriteTransaction {
IAsyncOperation CommitWithResultAsync();
}
public enum GattRequestState
public sealed class GattRequestStateChangedEventArgs
public sealed class GattServiceProvider
public enum GattServiceProviderAdvertisementStatus
public sealed class GattServiceProviderAdvertisementStatusChangedEventArgs
public sealed class GattServiceProviderAdvertisingParameters
public sealed class GattServiceProviderResult
public sealed class GattSession : IClosable
public enum GattSessionStatus
public sealed class GattSessionStatusChangedEventArgs
public enum GattSharingMode
public sealed class GattSubscribedClient
public sealed class GattUuid
public sealed class GattWriteRequest
public sealed class GattWriteRequestedEventArgs
public sealed class GattWriteResponse
public sealed class GattWriteResult
}
namespace Windows.Devices.Haptics {
public static class KnownSimpleHapticsControllerWaveforms
public sealed class SimpleHapticsController
public sealed class SimpleHapticsControllerFeedback
public enum VibrationAccessStatus
public sealed class VibrationDevice
}
namespace Windows.Devices.PointOfService {
public sealed class BarcodeScanner : IClosable {
void Close();
public static string GetDeviceSelector(PosConnectionTypes connectionTypes);
}
public static class BarcodeSymbologies {
public static uint Gs1DWCode { get; }
}
public sealed class BarcodeSymbologyAttributes
public enum BarcodeSymbologyDecodeLengthKind
public sealed class CashDrawer : IClosable {
void Close();
public static string GetDeviceSelector(PosConnectionTypes connectionTypes);
}
public sealed class ClaimedBarcodeScanner : IClosable {
IAsyncOperation GetSymbologyAttributesAsync(uint barcodeSymbology);
IAsyncOperation SetSymbologyAttributesAsync(uint barcodeSymbology, BarcodeSymbologyAttributes attributes);
}
public sealed class ClaimedLineDisplay : IClosable
public sealed class LineDisplay : IClosable
public sealed class LineDisplayCapabilities
public enum LineDisplayScrollDirection
public enum LineDisplayTextAttribute
public enum LineDisplayTextAttributeGranularity
public sealed class LineDisplayWindow : IClosable
public sealed class MagneticStripeReader : IClosable {
void Close();
public static string GetDeviceSelector(PosConnectionTypes connectionTypes);
}
public enum PosConnectionTypes : uint
public sealed class PosPrinter : IClosable {
void Close();
public static string GetDeviceSelector(PosConnectionTypes connectionTypes);
}
}
namespace Windows.Gaming.Input {
public sealed class ArcadeStick : IGameController, IGameControllerBatteryInfo {
public static ArcadeStick FromGameController(IGameController gameController);
BatteryReport TryGetBatteryReport();
}
public sealed class FlightStick : IGameController, IGameControllerBatteryInfo
public enum FlightStickButtons : uint
public struct FlightStickReading
public enum GameControllerSwitchKind
public enum GameControllerSwitchPosition
public sealed class Gamepad : IGameController, IGameControllerBatteryInfo {
public static Gamepad FromGameController(IGameController gameController);
BatteryReport TryGetBatteryReport();
}
public sealed class Headset : IGameControllerBatteryInfo {
BatteryReport TryGetBatteryReport();
}
public interface IGameControllerBatteryInfo
public sealed class RacingWheel : IGameController, IGameControllerBatteryInfo {
public static RacingWheel FromGameController(IGameController gameController);
BatteryReport TryGetBatteryReport();
}
public sealed class RawGameController : IGameController, IGameControllerBatteryInfo
public sealed class UINavigationController : IGameController, IGameControllerBatteryInfo {
public static UINavigationController FromGameController(IGameController gameController);
BatteryReport TryGetBatteryReport();
}
}
namespace Windows.Gaming.Input.Custom {
public static class GameControllerFactoryManager {
public static IGameController TryGetFactoryControllerFromGameController(ICustomGameControllerFactory factory, IGameController gameController);
}
public sealed class HidGameControllerProvider : IGameControllerProvider
public interface IHidGameControllerInputSink : IGameControllerInputSink
}
namespace Windows.Gaming.UI {
public enum GameChatMessageOrigin
public sealed class GameChatOverlay
public enum GameChatOverlayPosition
}
namespace Windows.Globalization {
public static class CurrencyIdentifiers {
public static string BYN { get; }
}
}
namespace Windows.Globalization.Collation {
public sealed class CharacterGroupings : IIterable, IVectorView {
public CharacterGroupings(string language);
}
}
namespace Windows.Graphics {
public struct PointInt32
public struct RectInt32
public struct SizeInt32
}
namespace Windows.Graphics.Display.Core {
public enum HdmiDisplayColorSpace
public struct HdmiDisplayHdr2086Metadata
public enum HdmiDisplayHdrOption
public sealed class HdmiDisplayInformation
public sealed class HdmiDisplayMode
public enum HdmiDisplayPixelEncoding
}
namespace Windows.Graphics.Holographic {
public sealed class HolographicCamera {
HolographicDisplay Display { get; }
HolographicCameraViewportParameters LeftViewportParameters { get; }
HolographicCameraViewportParameters RightViewportParameters { get; }
}
public sealed class HolographicCameraRenderingParameters {
HolographicReprojectionMode ReprojectionMode { get; set; }
void CommitDirect3D11DepthBuffer(IDirect3DSurface value);
}
public sealed class HolographicCameraViewportParameters
public sealed class HolographicDisplay
public enum HolographicReprojectionMode
public sealed class HolographicSpace {
public static bool IsAvailable { get; }
public static bool IsSupported { get; }
public static event EventHandler
API Removals:
namespace Windows.UI.Composition {
public sealed class CompositionDrawingSurface : CompositionObject, ICompositionSurface {
}
}
namespace Windows.UI.Composition.Interactions {
public sealed class VisualInteractionSource : CompositionObject, ICompositionInteractionSource {
}
}
About a year ago we released the new work item form to Visual Studio Team Services. This was the beginning of our vision for managing work items in a more social and visual way. Over the past year, we focused on realizing this vision through continual improvements and listening to customer feedback.
We added many useful features along the way, such as:
A discussion control with @mention support to better collaborate on a work item.
Ability to follow a work item to be notified when it changes.
A work item extensibility model which lets you extend the form with custom controls, groups and pages.
A responsive links control to better visualize related work.
Integrated development control to both track existing code assets and to create new ones.
An attachment control that supports drag/drop , uploading multiple files and image preview.
A more visual history control to better review changes.
With all these changes, we now have a modern and extensible work item form. And, we’re very excited that you’ll be able to access it with the TFS 2017 release.
Enabling the new form in TFS 2017
After installing TFS 2017, all newly created collections will have the new form enabled by default. However, since we know the new form is a big change we built an opt in experience for existing collections. This lets administrators enable the new work item form in stages and make changes to the layout before deploying it broadly.
Start by enabling the new form in the collection administration page
Once enabled you can configure who can see the new form:
We recommend that you start with enabling for Administrators so that you can review and apply changes until you are happy with the layout. When you are ready to share with the rest of your team, enable as opt-in for all users.
When enabled as opt-in, each user will see a link that lets them toggle to the new form and try it out. This gives the opportunity to test out the layout changes and give feedback.
Once you have made any necessary updates to the layout to address feedback, you can migrate everyone to the new form for a consistent management experience.
Anatomy of the new work item form
The new form consists of a System Header and Pages.
System header
The system header contains vital parts of the work item – this includes Title, Assigned To, Discussion indicator, Tags, Follow, as well as the History, Links and Attachment pages.
We have become more restrictive with the system header so that we can bring consistency and utility across all work item experiences. Currently, the only customization you can make to the system header is changing the labels. You can still customize the underlying fields through the rules. We are looking for your feedback on these changes, and any additional customization you may need on the system header.
Pages
All the other content of the work item is organized into Pages, represented as tabs on the form.
Each page consists of Sections – the picture below shows a page with 3 sections. The first section is allocated 60% of the page width, the other two sections are allocated 20% each.
Groups
Sections are made up of groups. For example, the second section (colored in blue) has 2 groups – Planning and Classification. You can collapse and expand groups. Also, you can maximize certain groups, such as those containing an HTML or rich-text field control.
Controls
Groups are containers of field or custom controls. For example, the Story Point field control is shown below.
By arranging the contents in sections the new form provides an adaptive experience based on the width of your screen. For wide screens, we give each section its own vertical column. However, for small screens we wrap sections to preserve space and readability.
Customizing the new work item form in TFS 2017
The new work item form has a simplified XML layout which is very easy to modify. The page, section, group and control elements map directly to what you see on the form.
When the new form is enabled you can export your work item type to see the new layout automatically added in the in the WebLayout node. This new layout is auto-generated by transforming your existing form layout. Below is an example of a simple form xml containing a couple groups and links controls:
Given that this is auto-generated, not everything may be perfect and to your liking but you can make changes and apply them using the familiar import command (witadmin importwitd).
The easiest way to do this is to export your work item type after the extension is installed. We inject a comment into the exported layout describing all extensions available targeting the work item form:
You can use this information to turn on extensions for your work item type and position them. In the example below, we add an Extension node that enables the Multi Value Control extension for the type and then add a ControlContribution node to add the custom control to the planning group.
After importing the work item type the custom control extension will show on the form.
We are planning a future blog post dedicated to work item form extensibility where we’ll go into greater depth about how to build them.
Conclusion
The new form landing in TFS 2017 culminates a lot of work and we are looking forward to receiving your feedback and exploring your ideas for improvements.
This week we have a new SDK, news about the Windows Developer Day – Windows 10 Creators Update, some curated C# tutorials, new Bluetooth features and if all that wasn’t enough, we created a desktop background featuring our favorite Visual Studio Shortcuts. We hope this desktop background can help both new and experienced developers learn a few tricks to help them become more efficient in Visual Studio. But first, here are last week’s updates:
Windows Developer Day – Windows 10 Creators Update
The Windows team would love to hear your feedback. Please keep the feedback coming using our Windows Developer UserVoice site. If you have a direct bug, please use the Windows Feedback tool built directly into Windows 10.
Starting this week, UWP links, which have been in the general .NET section until now, are getting their own section thanks to Michael Crump who graciously accepted to provide weekly contents along with Phillip Carter for F#, Stacey Haffner for gaming, and Dan Rigby for Xamarin.
This week, we’ll speak with David Pine about building a magic mirror. The show is on Thursdays and begins at 10AM Pacific Time on Channel 9. We’ll take questions on Gitter, on the dotnet/home channel and on Twitter. Please use the #onnet tag. It’s OK to start sending us questions in advance if you can’t do it live during the show.
Package of the week: Ammy
XAML is a way to describe instances of components. It uses an XML dialect, which is not to the taste of everyone, and may not be the best for manual authoring. The same ideas that XAML implements can however perfectly well be implemented with other persistence formats.
Ammy is one such format, that is inspired from JSON and Qt’s QML. It’s lightweight, expressive, and extensible.
Tool of the week: Concurrency Visualizer
Concurrency Visualizer is an invaluable extension to Visual Studio that helps you visualize multithreaded application performance. It can monitor processor and core utilization, threads, spot anti-patterns, and recommend best practices.
Eco is a global survival game with a focus on ecology and collaboration. In Eco, players must team up to build a civilization and evolve it quick enough to destroy an incoming meteor before it takes out the planet, but not so quickly that it destroys the ecosystem and everyone along with it. Eco takes the typical survival genre and puts a unique spin on it by providing a fully simulated ecosystem, where every single action taken affects the countless species, even the humans. (If not properly balanced, it is possible to destroy the food source and cause a server-wide perma-death.) Players also establish and run the government by enacting laws, a criminal justice system to enforce the laws and the economy by selling goods and services.
Eco was created Strange Loop Games using C# and Unity for the client and ASP.NET and the .NET Framework for their website and server backend. It is currently in alpha for Windows, Mac, and Linux. Eco is also being piloted in serveral schools as a means to teach students about ecology, collaboration and cause and effect.
User group meeting of the week: Serverless .NET Core app for the AWS IoT Button in San Diego, CA
As always, this weekly post couldn’t exist without community contributions, and I’d like to thank all those who sent links and tips. The F# section is provided by Phillip Carter, the gaming section by Stacey Haffner, the Xamarin section by Dan Rigby, and the UWP section by Michael Crump.
You can participate too. Did you write a great blog post, or just read one? Do you want everyone to know about an amazing new contribution or a useful library? Did you make or play a great game built on .NET?
We’d love to hear from you, and feature your contributions on future posts:
I've been a people manager as well as an IC (individual contributor) for a while now, and while I don't yet have the confidence to tell you I'm a good manager, I can tell you that I'm trying and that I'm introspective about my efforts.
The way it works is, on Mondays, you figure out the 3 outcomes you want for the week. Each day you identify 3 outcomes you want to accomplish. On Friday, you reflect on 3 things going well and 3 things to improve. It’s that simple. - J.D. Meier
We are a remote team and we are in three different time zones so the "morning standup" doesn't really work so well for us. We want a "scrum" style standup, but we're a team that lives in Email/Slack/Microsoft Teams/Skype.
Here's how Monday Vision works for us as a team. We are transparent about what we're working on and we are honest about what works and when we stumble.
On Monday morning each of us emails the team with:
What we hope to accomplish this week. Usually 3-5 things.
This isn't a complete list of everything on our minds. It's just enough to give context and a vector/direction.
It's important that we are clear on what our goals are. What would it take for this week to be amazing? What kinds of things are standing in our way? As a manager I think my job is primarily as traffic cop and support. My job is to get stuff out of my team's way. That might be paperwork, other teams, technical stuff, whatever is keeping them out of their flow.
These emails might be as simple as this (~real) example from a team member.
Last Week:
DevIntersection Conference
Workshop and 2 sessions
Got approval from Hunter for new JavaScript functionality
This Week:
Trip Report, Expenses, and general administrivia from the event last week
Final planning for MVP Summit
Spring Planning for ASP.NET Web Forms, IIS Express, EF4, WCF, and more
Modern ASP.NET Web Forms research paper
Thursday evening – presenting over Skype to the London.NET user-group “Introduction to Microservices in ASP.NET Core”
Again, the lengths and amount of detail vary. Here's the challenge part though - and my team hasn't nailed this yet and that's mostly my fault - Friday Reflection. I have an appointment on my calendar for Friday at 4:30pm to Reflect. This is literally blocked out time to look back and ask these questions....
On Friday evening on the way out, email the team with:
What worked this week? Why didn't Project Foo get done? Was the problem technical? Logistical? Organizational?
Did you feel amazing about this week? Why? Why not? How can we make next week feel better?
What do you do to kick off and close down your week?
Sponsor: Big thanks to Raygun! Join 40,000+ developers who monitor their apps with Raygun. Understand the root cause of errors, crashes and performance issues in your software applications. Installs in minutes, try it today!
Software Company, IncaX, uses Bing Maps as part of its CopTrax solution, which streams live video from a police officer’s vehicle or body camera and stores it in the cloud. To better pinpoint officers’ locations and reconstruct details of police activity, IncaX incorporated mapping into its solution. Now, IncaX law enforcement customers use CopTrax to make more informed day-to-day decisions, reduce IT administration, and respond more quickly to critical incidents.
"We had a lot of considerations, and Bing Maps ticked all the boxes for us. With it, we get a completely flexible mapping solution," says Phil Bishop, IncaX Owner and Chief Technology Officer.
This time last year we did a Microsoft Virtual Academy class on what was then called "ASP.NET 5." It made sense to call it 5 since 5 > 4.6, right? But since then ASP.NET 5 has become .NET Core 1.0 and ASP.NET Core 1.0. It's 1.0 because it's smaller, newer, and different. As the .NET "full" framework marches on, on Windows, .NET Core is cross-platform and for the cloud.
Command line concepts like dnx, dnu, and dnvm have been unified into a single "dotnet" driver. You can download .NET Core at http://dot.net and along with http://code.visualstudio.com you can get a web site up and running in 10 minutes on Windows, Mac, or many flavors of Linux.
So, we've decided to update and refresh our Microsoft Virtual Academy. In fact, we've done three days of training. Introduction, Intermediate, and Cross-Platform and all three days are now available! We just released training for ASP.NET Core 1.0 Cross-Platform that shows Mac, Ubuntu, and Docker!
Join experts Scott Hanselman and Maria Naggaga, and find out how to build .NET Core applications on any operating system. Bring your web development expertise and roll up your sleeves, for this first in a three-part series.
Want a deeper dive into ASP.NET Core 1.0? Build on what you learned in Introduction to ASP.NET Core 1.0, and explore this new technology even further, as Scott Hanselman, Jeff Fritz, and Rowan Miller offer an in-depth, intermediate-level look at ASP.NET Core 1.0.
Ready to build and deploy ASP.NET Core 1.0 apps? Join experts Scott Hanselman, Maria Naggaga, and Glenn Condron, and see how to do just that using Mac and Linux. Revisit content from the Introduction to ASP.NET Core 1.0 course, but using a Mac and Linux.
Do us a favor when you watch these, rate them (5 stars!) and SHARE them on your social networks.
NOTE: There's a LOT of quality free courseware for learning .NET Core and ASP.NET Core. We've put the best at http://asp.net/free-courses and I encourage you to check them out!
Hope you have as much fun with these courses as we had creating them!
Sponsor: Do you deploy the same application multiple times for each of your end customers? The team at Octopus have taken the pain out of multi-tenant deployments. Check out their latest 3.4 release
The UWPDesktop NuGet package is here to improve the developer experience with Visual Studio when walking along the Desktop Bridge.
The Desktop Bridge allows you to call UWP APIs directly from your WinForms, WPF or VB application. You can use APIs such as Live tiles, notifications, App Services and many more!
Previously, calling UWP APIs from a converted app was a confusing process. You had to find and reference the right .dll or .winmd, and it often wasn’t obvious which one to choose.
For example, to use “await” on UWP types, you had to reference the System.Runtime.WindowsRuntime.dll (c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\
System.Runtime.WindowsRuntime.dll), which was actually from Windows 8.1 and therefore only worked in conjunction with “facade\windows.winmd” (c:\Program Files (x86)\Windows Kits\10\UnionMetadata\Facade\Windows.WinMD).
AppServiceConnectionStatus status = await connection.OpenAsync();
Confusing, right? The new way is much simpler – just include the latest UWPDesktop NuGet package to your project, and you’re ready to call any supported UWP API without needing additional references.
You have two options for installing the package:
In Visual Studio, right-click on your project, select “Manage NuGet Packages,” and search for and install the UWPDesktop package (as shown in the screenshot below):
Not all modern APIs can be called directly from your desktop application; for example, you still can’t use XAML or SecondaryTile in your WinForms app. The UWPDesktop NuGet package makes your life easier by raising a warning if you try and call an unsupported API.
For more information and to learn more about the UWPDesktop NuGet package and Desktop Bridge, check out the resources below.
Last week, David Pine was on the show to talk about his magic mirror, a screen in a mirror, that can display useful information such as his schedule for the day, the weather forecast, and much more. The mirror uses a Raspberry Pi 3 running Windows 10 IoT Core, and runs a custom, open-source UWP application. It also has a camera, microphone, and sound bar, enabling voice-based interactions.
This week, we’ll talk about the year ahead for .NET. The list of guests is still TBD as I’m writing this, but I hope to have some good surprises. We’ll take questions on Gitter, on the dotnet/home channel and on Twitter. Please use the #onnet tag. It’s OK to start sending us questions in advance if you can’t do it live during the show.
One such alternative is “magic links”, that are nonces that the application usually sends to an email address or phone number that is known to belong to the user.
Even though PwdLess is built with .NET, it’s usable from any platform through its simple HTTP API. GET /auth/sendNonce?identifier=[IDENTIFIER] sends the nonce, and GET /auth/nonceToToken?nonce=[NONCE] responds 200 with the JWT if the nonce is valid.
PwdLess configuration is done through a simple JSON file:
Game of the week: Terraria
Terraria is an incredibly popular 2D adventure-survival game that blends classic action game mechanics with sandbox style freedom. In Terraria, players dig, fight and explore the world gathering materials that can be used to craft gear, machinery, and dwellings. You can seek out foes that grow in difficulty as you build up your very own city, giving allies that you encounter along your travels a place to stay. Terraria features randomly generated open worlds, a vast amount of weapons and armor, and numerous crafting options.
Terraria was created by Re-Logic using C# and XNA. It is available on Steam for Windows and Mac, Xbox 360, Xbox One, PlayStation 3, PlayStation 4, PSVita, Android and iOS.
User group meeting of the week: migrating from TFS to the cloud in Sydney
As always, this weekly post couldn’t exist without community contributions, and I’d like to thank all those who sent links and tips. The F# section is provided by Phillip Carter, the gaming section by Stacey Haffner, and the Xamarin section by Dan Rigby, and the UWP section by Michael Crump.
You can participate too. Did you write a great blog post, or just read one? Do you want everyone to know about an amazing new contribution or a useful library? Did you make or play a great game built on .NET?
We’d love to hear from you, and feature your contributions on future posts:
In the last post, we introduced you to a video series from Bob Tabor that teaches the fundamentals of C#. In this post, you’ll learn how to put those new (or re-sharpened) C# skills to use as we explore UWP (Universal Windows Platform) development in the Windows 10 Development for Absolute Beginners course from Bob Tabor. With little or no prior experience with XAML (pronounced “Zammal”), you’ll learn how to use XAML and C# to create amazing Windows 10 UWP applications, get those apps ready for publishing and see them run on UWP devices ranging from Xbox One and PC, to mobile and even Raspberry Pi.
Even if you’re an experienced UWP developer, just like in the last post, you may find that there are areas you’d like to brush up on. You can jump to any of the course’s 80 videos and also explore the companion sample code on GitHub.
Exploring the Course
The Ultimate Beginner Series course has two conceptual parts. In the first half, Bob Tabor explains the concepts, patterns and features of a UWP application. In the second half, you will build out four fleshed-out demo applications. From “File > New” to submitting your app to the Windows Store, these samples will get you ready to build and publish your first (or next) app!
First Half
Let’s take a high-level look at just some of the topics you’ll see in the front half of the course (to see the full list visit the course site).
Videos 1– 7: Introduction to both XAML and what UWP (Universal Windows Application) is
Videos 8– 18: Learn how to use different XAML Layouts
Videos 37– 39: VisualStateManager and AdaptiveTriggers
Videos 40– 42: DataBinding, ObservableCollections and DataTemplates
There’s a lot there and there is even more to see, including lesson cheat-sheets, challenges and other useful material for learning and future reference.
Second Half
Now, let’s take a look at the four big samples that you’ll build as you move into the second part of the course. These videos will bring you through all the aspects of building, testing and publishing a UWP app.
Databinding the object graph from the Web API results
Displaying that data in an adaptive layout
Make it through everything? Congrats, you are now ready to begin (or continue) your journey into the world of Windows 10 UWP development. This is not the end of great resources, there are many more available to you as you continue on your journey as a UWP developer (see resources section below). We look forward to seeing the wonderful UWP creations you bring to the Windows Store in 2017!
The Windows team would love to hear your feedback. Please keep the feedback coming using our Windows Developer UserVoice site. If you have a direct bug, please use the Windows Feedback tool built directly into Windows 10.
The main release branch of the Bing Maps Version 8 web control (V8) has been in a code freeze over the last two months for the holiday season. Over this time the Bing Maps team focused primarily on bug fixes and performance improvements in Bing Maps V8. Here are some of the more notable new features added in this release.
Cardinal Splines
The Spatial Math module has a new function that calculates a cardinal spline that passes through a specified array of locations.
Some applications will sometimes want to display two or more maps on a single page. With this release, the Bing Maps V8 web control now supports loading multiple map instances on a single page.
Route Path Locations
When you calculate a route using the directions manager, you can now easily get an array of locations that make up the route path. This is useful if you want to create a custom styled route line on the map, or if you want to perform route-based calculations such as search for data along or near a route. Combine this with the Bing Maps REST elevation service and easily generate route elevation profiles. This is documented as part of the Route response object here.
In Summary
A complete list of new features added in this release can be found on the What’s New page in the documentation on MSDN. We have many other features and functionalities on the road map for Bing Maps V8. If you have any questions or feedback about V8, please let us know on the Bing Maps forums or visit the Bing Maps website to learn more about our V8 web control features.
Image processing, and in particular image resizing, is a common requirement for web applications. As such, I wanted to paint a panorama of the options that exist for .NET Core to process images. For each option, I’ll give a code sample for image resizing, and I’ll outline interesting features. I’ll conclude with a comparison of the performance of the libraries, in terms of speed, size, and quality of the output.
CoreCompat.System.Drawing
If you have existing code relying on System.Drawing, using this library is clearly your fastest path to .NET Core and cross-platform bliss: the performance and quality are fine, and the API is exactly the same. The built-in System.Drawing APIs are the easiest way to process images with .NET Framework, but they rely on the GDI+ features from Windows, which are not included in .NET Core, and are a client technology that was never designed for multi-threaded server environments. There are locking issues that may make this solution unsuitable for your applications.
ImageSharp is a brand new, pure managed code, and cross-platform image processing library. Its performance is not as good as that of libraries relying on native OS-specific dependencies, but it remains very reasonable. Its only dependency is .NET itself, which makes it extremely portable: there is no additional package to install, just reference ImageSharp itself, and you’re done.
If you decide to use ImageSharp, don’t include the package that shows on NuGet: that’s going to be an empty placeholder until the first official release of ImageSharp ships. For the moment, you need to get a nightly build from a MyGet feed. This can be done by adding the following NuGet.config to the root directory of the project:
For a new codebase, the library is surprisingly complete. It includes all the filters you’d expect to treat images, and even includes very comprehensive support for reading and writing EXIF tags (that code is shared with Magick.NET):
Note that the latest builds of ImageSharp are more modular than they used to, and if you’re going to use image formats such as Jpeg, or image processing capabilities such as Resize, you need to import additional packages in addition to the core ImageSharp package (respectively ImageSharp.Processing and ImageSharp.Formats.Jpeg).
Magick.NET is the .NET wrapper for the popular ImageMagick library. ImageMagick is an open-source, cross-platform library that focuses on image quality, and on offering a very wide choice of supported image formats. It also has the same support for EXIF as ImageSharp.
The .NET Core build of Magick.NET currently only supports Windows. The author of the library, Dirk Lemstra is looking for help with converting build scripts for the native ImageMagick dependency, so if you have some expertise building native libraries on Mac or Linux, this is a great opportunity to help an awesome project.
Magick.NET has the best image quality of all the libraries discussed in this post, as you can see in the samples below, and it performs relatively well. It also has a very complete API, and the best support for exotic file formats.
The first benchmark loads, resizes, and saves images on disk as Jpegs with a a quality of 75. I used 12 images with a good variety of subjects, and details that are not too easy to resize, so that defects are easy to spot. The images are roughly one megapixel JPEGs, except for one of the images that is a little smaller. Your mileage may vary, depending on what type of image you need to work with. I’d recommend you try to reproduce these results with a sample of images that corresponds to your own use case.
For the second benchmark, an empty megapixel image is resized to a 150 pixel wide thumbnail, without disk access.
The benchmarks use .NET Core 1.0.3 (the latest LTS at this date) for CoreCompat.System.Drawing, ImageSharp, and Magick.NET, and Mono 4.6.2 for SkiaSharp.
I ran the benchmarks on Windows on a HP Z420 workstation with a quad-core Xeon E5-1620 processor, 16GB of RAM, and the built-in Radeon GPU. For Linux, the results are for the same machine as Windows, but in a 4GB VM, so lower performance does not mean anything regarding Windows vs. Linux performance, and only library to library comparison should be considered meaningful. The macOS numbers are on an iMac with a 1.4GHz Core i5 processor, 8GB of RAM, and the built-in Intel HD Graphics 5000 GPU, running macOS Sierra.
Results are going to vary substantially depending on hardware: usage and performance of the GPU and of SIMD depends on both what’s available on the machine, and on the usage the library is making of it. Developers wanting to get maximum performance should further experiment. I should mention that I had to disable OpenCL on Magick.NET (OpenCL.IsEnabled = false;), as I was getting substantially worse performance with it enabled on that workstation than on my laptop.
Library
Load, resize, save (ms)
Resize (ms)
CoreCompat.System.Drawing
34 ± 1
16.0 ± 0.6
ImageSharp
63 ± 1
14.8 ± 0.8
Magick.NET
62 ± 1
22.7 ± 0.7
SkiaSharp
16 ± 1
2.5 ± 0.1
For both metrics, lower is better.
Library
Load, resize, save (ms)
Resize (ms)
CoreCompat.System.Drawing
93 ± 1
71.5 ± 0.3
ImageSharp
94.2 ± 0.4
40.6 ± 0.8
SkiaSharp
15.6 ± 0.1
3.29 ± 0.03
For both metrics, lower is better.
Library
Load, resize, save (ms)
Resize (ms)
CoreCompat.System.Drawing
114 ± 5
92 ± 1
ImageSharp
178 ± 5
95 ± 1
For both metrics, lower is better.
Library
File Size (kB)
CoreCompat.System.Drawing
4.0
ImageSharp
3.3
Magick.NET
4.2
SkiaSharp
3.1
Lower is better. Note that file size is affected by the quality of the subsampling that’s being performed, so size comparisons should take into account the visual quality of the end result.
Quality comparison
Here are the resized images. As you can see, the quality varies a lot from one image to the next, and between libraries. Some images show dramatic differences in sharpness, and some moiré effects can be seen in places. You should make a choice based on the constraints of your project, and on the performance vs. quality trade-offs you’re willing to make.
CoreCompat.System.Drawing
ImageSharp
Magick.NET
SkiaSharp
Conclusions
There is today a good choice of libraries for image processing on .NET Core, that can fit different requirements, with even more great choices coming in the near future.
If performance is your priority, CoreCompat.System.Drawing is a good choice today if the possible lock issues in Windows server scenarios are not a showstopper for your application. SkiaSharp, when available on .NET Core, will be a fantastic choice.
If quality or file type support is your priority, Magick.NET is the clear winner. Cross-platform support is not quite there yet, however, but you can help.
Finally, the only pure managed code library available at this point, ImageSharp, is an excellent choice. Its performance is close to that of Magick.NET, and the fact that it has no native dependencies means that the library is guaranteed to work everywhere .NET Core works. The library is still in alpha, and significant performance improvements are in store, notably with future usage of Span and ref returns.
Acknowledgements
All four libraries in this post are open-source, and only exist thanks to the talent and generosity of their authors, contributors and maintainers. In particular,
James Jackson South wrote ImageSharp. James was extremely helpful while I was preparing this post, and even contributed sample code.
Dirk Lemstra wrote Magick.NET. Dirk was also super-patient and nice, and helped me fix some performance issues I had on my benchmark machine. He also fixed my sample code.
VSTest is a very extensible unit test execution framework. The base engine, discovers tests and runs them. It can parallelize across cores, provides process isolation and can integrate with Visual Studio. It has extensibility for different test frameworks, code coverage, test impact analysis, data collection, test result reporting and much more.
To give you a little context on what I’m talking about I’ve put together an architecture diagram. The pieces we open sourced yesterday are in yellow. My diagram of the end to end solution includes clients like VS and VSCode (and others) on the left – though you can just use the command line directly and just skip that swim lane. We released our cross platform runner and the host process that discovers, loads and runs the tests.
Tests generally use some test framework and vstest supports many. Many of the test adapters are open source or available as NuGet packages. You can checkout the VS marketplace for a sampling of them. We did not open source any new adapters with this release – but we don’t even build most of them. The big one we do build is MSTestV2 and VERY MANY people use it. We did not open source that framework at this time but we plan to in the next few months – it just wasn’t ready at this time.
If you use unit testing in VS, there’s a good chance you use this infrastructure already. If you are using the unit testing capabilities that have been delivered in the .NET Core previews, you are also using it. Now it is open source so you can see how it works and, ultimately, contribute to it. We have not yet opened up the project for contributions but we will. Again, crawl, walk, run.
Thanks and, as always, any feedback or questions are welcome
This week we have updates for both new and experienced developers alike! Take a look below to see the latest news from the Windows Developer team.
New year, new dev: Developing your idea into a UWP app
With little or no prior experience, you’ll learn how to use XAML and C# to create amazing Windows 10 UWP applications, get those apps ready for publishing and see them run on UWP devices ranging from Xbox One and PC, to mobile and even Raspberry Pi. Get started here:
Turn your idea into a publishable app! Learn how to create the apps you've always wanted to build right here: https://t.co/O9mKecO29n
The UWPDesktop NuGet package is here to improve the developer experience with Visual Studio when walking along the Desktop Bridge.
The Desktop Bridge allows you to call UWP APIs directly from your WinForms, WPF or VB application. You can use APIs such as Live tiles, notifications, App Services and many more!
Add the latest UWPDesktop NuGet package to your project to call any supported UWP API w/o additional references. https://t.co/Ob3zagTO1s
And finally, in case you missed it last week, here is the Visual Studio Shortcuts desktop background we mentioned above. Download it here: http://wndw.ms/FkkoWL
The Windows team would love to hear your feedback. Please keep the feedback coming using our Windows Developer UserVoice site. If you have a direct bug, please use the Windows Feedback tool built directly into Windows 10.
We are excited to announce that we have launched over 8.5 million square kilometers of fresh imagery for Brazil on Bing Maps. This imagery release covers the total area of Brazil, including land and water.
With stunning imagery of shores like those in Copacabana, you can just feel the ocean breeze on your face. Below is an aerial image of the Copacabana that has one of the most iconic beaches in the world. All year round people relax along the 4 kilometers of beautiful sand beach, play beach volleyball, soccer, party or just enjoy life. On New Year’s Eve the beach attracts millions of locals and tourists for a party without equal.
Below is another great scene from Brazil’s aerial imagery. This is a view of Third Bridge (Terceira Ponte) in Vitoria, which connects Vitoria to the city Vila Velha in the state of Espirito Santo, Brazil. Terceira Ponte is the second tallest bridge in Brazil.
Explore this unique place and many more marvels of Brazil on Bing Maps.