Академический Документы
Профессиональный Документы
Культура Документы
CONTENTS
14 DIAGNOSTIC USING
ANALYZERS
IN VISUAL STUDIO 2015 EDGE.JS
to combine
20 DEVOPS
Node.js and .NET
ON
AZURE 06
28 WPF
ITEMSCONTROL -
PART 2
46 OPEN
CLOSED Building a
PRINCIPLE Sound Cloud Music
SOFTWARE GARDENING:
SEEDS Player in
Windows 10 50
62 NEW
BUILD FEATURES
IN Using
TFS 2015 AND
VISUAL STUDIO ONLINE
Bootstrap, jQuery and
Hello.js to integrate
76 USING NEW XAML TOOLS IN Social Media
VISUAL STUDIO 2015 in your Websites 68
TEAM AND FROM THE
CREDITS EDITOR
Editor In Chief
Suprotim Agarwal
suprotimagarwal@a2zknowledgevisuals.com
Art Director
Minal Agarwal
minalagarwal@a2zknowledgevisuals.com
Contributing Authors
Craig Berntson
Damir Arh
Suprotim Agarwal Editor in Chief
Edin Kapic
Gouri Sohoni
Irwin Dominin We had a gala time in July releasing our 3rd
Kent Boogaart Anniversary Edition. Overall it was a huge success
Mahesh Sabnis with over 77K downloads. We also received tons
Ravi Kiran of appreciation and feedback. In the next edition
Shoban Kumar (November), you will see articles on React.js, Node.js
Subodh Sohoni and Angular.js as a direct result of this feedback.
Windows, Visual Studio, ASP.NET, Azure, TFS & other Microsoft products & technologies are trademarks of the Microsoft group of companies. ‘DNC Magazine’ is an independent
publication and is not affiliated with, nor has it been authorized, sponsored, or otherwise approved by Microsoft Corporation. Microsoft is a registered trademark of Microsoft
corporation in the United States and/or other countries.
EDGE.JS
USING
Hello World using Edge We can rewrite the same Edge.js proxy creation by
passing the C# code in the form of a string instead
of a multiline comment. Following snippet shows
Edge.js can be added to a Node.js application this:
through NPM. Following is the command to install
the package and save it to package.json file: var helloWorld = edge.func(
'async(input) => {'+
> npm install edge --save 'return "Hurray! Inline C# works
with edge.js!!!";'+
The edge object can be obtained in a Node.js file as: '}'
);
var edge = require('edge');
We can pass a class in the snippet and call a
method from the class as well. By convention, name
The edge object can accept inline C# code, read
of the class should be Startup and name of the
code from a .cs or .csx file, and also execute the
method should be Invoke. The Invoke method will
code from a compiled dll. We will see all of these
be attached to a delegate of type Func<object,
approaches.
Task<object>>. The following snippet shows
usage of class:
To start with, let’s write a “Hello world” routine
inline in C# and call it using edge. Following
It can be invoked the same way we did previously:
snippet defines the edge object with inline C# code:
helloFromClass(10, function (error,
var helloWorld = edge.func(function () { result) {
/*async(input) => { if(error){
return "Hurray! Inline C# works with console.log("error occured...");
edge.js!!!"; console.log(error);
}*/ return;
}); }
console.log(result);
The asynchronous and anonymous C# function
});
passed in the above snippet is compiled
dynamically before calling it. The inline code has
to be passed as a multiline comment. The method A separate C# file
edge.func returns a proxy function that internally
calls the C# method. So the C# method is not called Though it is possible to write the C# code inline,
till now. Following snippet calls the proxy: being developers, we always want to keep the code
www.dotnetcurry.com/magazine 7
in a separate file for better organization of the CREATE TABLE Employees(
code. By convention, this file should have a class Id INT IDENTITY PRIMARY KEY,
called Startup with the method Invoke. The Invoke Name VARCHAR(50),
method will be added to the delegate of type Occupation VARCHAR(20),
Salary INT,
Func<object, Task<object>>. City VARCHAR(50)
);
Following snippet shows content in a separate file,
Startup.cs: INSERT INTO Employees VALUES
('Ravi', 'Software Engineer', 10000,
using System.Threading.Tasks; 'Hyderabad'),
('Rakesh', 'Accountant', 8000,
public class Startup { 'Bangalore'),
public async Task<object> ('Rashmi', 'Govt Official', 7000,
Invoke(object input) { 'Delhi');
return new Person(){
Name="Alex", Open Visual Studio, create a new class library
Occupation="Software project named EmployeesCRUD and add a new
Professional",
Entity Data Model to the project pointing to the
Salary=10000,
City="Tokyo" database created above. To make the process of
}; consuming the dll in Edge.js easier, let’s assign
} the connection string inline in the constructor of
} the context class. Following is the constructor of
context class that I have in my class library:
public class Person{
public string Name { get; set; }
public EmployeesModel()
public string Occupation { get; set; }
public double Salary { get; set; } : base("data source=.;initial
public string City { get; set; } catalog=EmployeesDB;
} integrated security=True;
MultipleActiveResultSets=True;
Performing CRUD
App=EntityFramework;") {}
Server
EmployeesOperations.cs. This file will contain the
methods to interact with Entity Framework and
perform CRUD operations on the table Employees.
Now that you have a basic idea of how Edge.js As a best practice, let’s implement the interface
works, let’s build a simple application that performs IDisposable in this class and dispose the context
CRUD operations on a SQL Server database using object in the Dispose method. Following is the basic
Entity Framework and call this functionality from setup in this class:
Node.js. As we will have a considerable amount of
code to setup Entity Framework and perform CRUD public class EmployeesOperations :
operations in C#, let’s create a class library and IDisposable {
EmployeesModel context;
consume it using Edge.js.
public EmployeesOperations() {
context = new EmployeesModel();
Creating Database and Class }
public void Dispose() {
Library context.Dispose();
}
As a first step, create a new database named }
EmployeesDB and run the following commands to
create the employees table and insert data into it: As we will be calling methods of this class directly
The same rule applies to the edit method as well. It Run NPM install to get these packages installed in
is shown below: the project. Add a new file to the project and name
it ‘server.js’. This file will contain all of the Node.js
public async Task<object> code required for the application. First things first,
EditEmployee(object input) { let’s get references to all the packages and add the
var empAsDictionary = required middlewares to the Express.js pipeline.
(IDictionary<string, object>)input; Following snippet does this:
var id = (int)empAsDictionary["Id"];
var edge = require('edge');
var employeeEntry = context.Employees. var express = require('express');
SingleOrDefault(e => e.Id == id); var bodyParser = require('body-parser');
www.dotnetcurry.com/magazine 9
var app = express(); Implementation of REST APIs for add and edit are
similar to the one we just saw. The only difference is,
app.use('/', express. they pass an input object to the proxy function.
static(require('path').join(__dirname,
'scripts')));
app.post('/api/employees', function
app.use(bodyParser.urlencoded({ (request, response) {
extended: true })); var addEmployeeProxy = edge.func({
app.use(bodyParser.json()); assemblyFile:"dlls\\EmployeeCRUD.
dll",
Now, let’s start adding the required Express REST typeName:"EmployeeCRUD.
EmployeesOperations",
APIs to the application. As already mentioned, the methodName: "AddEmployee"
REST endpoints will interact with the compiled dll });
to achieve their functionality. The dll file can be addEmployeeProxy(request.body,
referred using the edge.func function. If type and apiResponseHandler(request, response));
method are not specified, it defaults class name as });
Startup and method name as Invoke. Otherwise, we
app.put('/api/employees/:id', function
can override the class and method names using the (request, response) {
properties in the object passed into edge.func. var editEmployeeProxy = edge.func({
assemblyFile:"dlls\\EmployeeCRUD.
Following is the REST API that returns list of dll",
employees: typeName:"EmployeeCRUD.
EmployeesOperations",
methodName: "EditEmployee"
app.get('/api/employees', function });
(request, response) { editEmployeeProxy(request.body,
var getEmployeesProxy = edge.func({ apiResponseHandler(request, response));
assemblyFile: 'dlls\\EmployeeCRUD. });
dll',
typeName: 'EmployeeCRUD.
EmployeesOperations', Consuming APIs on a Page
methodName: 'GetEmployees'
}); The final part of this tutorial is to consume these
APIs on an HTML page. Add a new HTML page to the
getEmployeesProxy(null,
apiResponseHandler(request, response)); application and add bootstrap CSS and Angular.js
}); to this file. This page will list all the employees and
provide interfaces to add new employee and edit
The function apiResponseHandler is a curried generic details of an existing employee. Following is the
method for all the three REST APIs. This function mark-up on the page:
returns another function that is called automatically
once execution of the .NET function is completed.
<!doctype html>
Following is the definition of this function:
<html>
<head>
function apiResponseHandler(request, <title>Edge.js sample</title>
response) { <link rel="stylesheet" href="https://
return function(error, result) { maxcdn.bootstrapcdn.com/bootstrap/
if (error) { 3.3.5/css/bootstrap.min.css"/>
response.status(500).send({error: </head>
error}); <body ng-app="edgeCrudApp">
return; <div class="container" ng-
} controller="EdgeCrudController as vm">
response.send(result); <div class="text-center">
}; <h1>Node-Edge-.NET CRUD Application
} </h1>
<hr/>
www.dotnetcurry.com/magazine 11
edgeCrudSvc.addEmployee(vm. });
employee) }
.then(function (result) {
resetForm(); return {
getAllEmployees(); getEmployees: getEmployees,
}, function (error) { addEmployee: addEmployee,
console.log("Error while editEmployee: editEmployee
inserting new employee"); };
console.log(error); });
}); }());
}
}; Save all the files and run the application. You
vm.reset= function () { should be able to add and edit employees. I am
resetForm(); leaving the task of deleting employee as an
}; assignment to the reader.
function resetForm(){
vm.employee = {}; Conclusion
vm.addEditEmployee.$setPristine();
} Generally it is challenging to make two different
frameworks talk to each other. Edge.js takes
vm.edit = function(emp){
vm.employee = emp; away the pain of integrating two frameworks
}; and provides an easier and cleaner way to take
advantage of good features of .NET and Nodejs
getAllEmployees(); together to build great applications. It aligns
}); with the Node.js event loop model and respects
execution model of the platform as well. Let’s thank
app.factory('edgeCrudSvc', function
($http) { Tomasz Jancjuk for his great work and use this tool
var baseUrl = '/api/employees'; effectively!
Visual Studio 2015 is finally delivering the results of project Roslyn – an ambitious
attempt at rewriting the C# and Visual Basic compilers as a service. One of the benefits is
the support for diagnostic analyzers in the code editor. They are small pieces of code for
validating and refactoring different aspects of source code, which can easily be written by
any developer wanting to improve his development experience in Visual Studio.
This article will help you learn everything you need to know about diagnostic analyzers,
and hopefully convince you that for your everyday development, you need to start using
them as soon as you switch to Visual Studio 2015.
You can download the Free Visual Studio 2015 Community Edition if you haven’t already.
Improvements in the Adding Diagnostic
Code Editor Analyzers to a Project
Visual Studio code editor has always performed With the new code editor, it is now possible to
background static code analysis to provide extend the built-in static code analysis on a per-
developers with information about errors and project basis. To install a so-called diagnostic
warnings in code. Instead of having to build the analyzer into a project, NuGet package manager is
project and finding these errors and warnings in used. To open the NuGet window, right click on the
compiler output, they can be visualized directly in project in Solution Explorer and select Manage NuGet
the source code, using squiggly lines below the Packages… from the context menu. Visual Studio
offending code. 2015 includes NuGet 3, which opens a dockable
window instead of a modal dialog, as was the case
in the previous version.
External Diagnostic
Analyzers in Action
To see them in action, create a new class in your
project containing the following code:
www.dotnetcurry.com/magazine 15
using System; Inside it is a new sub-node called Analyzers,
using System.Runtime.Serialization; which contains all the analyzers installed with
our package. The rules are grouped by their
namespace ClassLibrary3 { assembly; each one of them having an icon in
public class SerializableClass :
ISerializable { front, representing its severity: Error, Warning, Info,
public void Hidden, or None.
GetObjectData(SerializationInfo
info, StreamingContext context) {
throw new
NotImplementedException();
}
}
}
www.dotnetcurry.com/magazine 17
in comparison to the previous versions – the main
reason being the inclusion of Roslyn. Diagnostic
analyzers might be the most important single
addition to Visual Studio as a side product of that
change.
The aircraft and the pilot ecosystem has to take Let us first take a simple example. A case where
constant evasive and attacking actions, in response your team is given a task of creating a POC of a
to similar actions taken by the enemy aircraft. In web application so that customer can view that
this example, one has to assume that the aircraft POC and give budgetary sanctions for full-fledged
is built to take evasive actions required in the application. You have decided that you will use
dogfight. If one imagines a passenger or bomber Visual Studio to develop that POC, Visual Studio
aircraft in place of the fighter aircraft, they will not Online to do the source control with build and you
be able to take those evasive actions. Extending will use Azure service to create a web application.
this example to the teams that are developing
software development, the teams that can take Let us start by creating that web application say
quick actions on changes detected in environment, called as “SSGSEMSWebApp”. This application will
like change in a business situation or rules of the have the domain of azurewebsites.net which is OK
business; is an Agile team. Like a passenger aircraft for us since it is only a POC. Once the application
cannot be agile, not every team is Agile. Teams have is provisioned, we will configure it to be deployed
to change or be recreated as an Agile team. A slow from source control by integrating it with VSO
lumbering team cannot become Agile just like that, source control.
by following some Agile practices.
2. Ensure the quality of services provided to the Figure 1: Create a Web Application on Azure
customer like availability, performance, scalability,
security etc. One assumption here is that we have already
created a team project on VSO to integrate with this
3. When maintaining the quality of services requires Azure web application. Right now there is nothing
some action from development team; operations under the source control of that team project but
team should provide the necessary feedback for that we can link that with our web application. The
action. name of that team project is say “SSGS EMS Demo”.
www.dotnetcurry.com/magazine 21
Figure 2: Connect Web App with VSO for Source Control
Figure 4: Create ASP.NET Application in Visual Studio Figure 7: Continuous Deployment on Azure
www.dotnetcurry.com/magazine 23
with similar names. For that we have to provide the Final step is to create a release template where for
subscription details of Azure since we are creating each stage, we can configure which deployment
the environments that are made up of Virtual actions have to take place and which tools are to be
Machines in Azure. One thing to remember is that used for those actions. For Azure VMs, we are going
all VMs that are to be part of same environment, to use PowerShell DSC script. We have to keep that
have to be in the same Cloud Service. In fact, when as part of the project and then provide necessary
we select Azure as the target for environments, the details to the deployment step.
wizard shows the names of the Cloud Services in
our subscription as possible candidates to create
environments.
www.dotnetcurry.com/magazine 25
Azure also provides the Puppet Agent to be
installed on the VMs to be provisioned. We may also
install the add-in provided by Puppet Labs to start
creating the configuration scripts in Visual Studio.
Puppet works on a similar concept but it has a Our script can be put on the Puppet Forge (a shared
server part of the software that has to be installed resource repository) using the same add-in in Visual
on one of our machines. It is called the Puppet Studio, and then can be used from a ssh command
Master. Azure provides a VM template for Puppet prompt of target machine.
Master.
Summary
www.dotnetcurry.com/magazine 27
WPF
Part 2
W
ItemsControl
Introduction
1
OK, we could move the margin into a resource and share that resource, but that’s still painful.
Figure 1: The container for items in a vanilla ItemsControl is a ContentPresenter
Thus, we can modify our XAML to specify a Margin Just as the DataTemplate property has a
for the ContentPresenter hosting each of our corresponding DataTemplateSelector property,
items: so too the ItemContainerStyle property has a
<ItemsControl corresponding ItemContainerStyleSelector.
ItemsSource="{Binding}" The mechanics of this property are exactly the same
ItemTemplateSelector="{StaticResource as DataTemplateSelector, so I won’t be going
PlaceDataTemplateSelector}"> into the details here. The only difference is you’re
<ItemsControl.ItemContainerStyle>
<Style TargetType="ContentPresenter"> returning a Style instead of a DataTemplate.
<Setter Property="Margin" Value="6 3 In choosing the Style, you’re privy to the
6 3"/> same information as you are when choosing a
</Style> DataTemplate: the item itself, and the container
</ItemsControl.ItemContainerStyle> for the item.
</ItemsControl>
When you have many items in a list, it’s often
This gives us the more aesthetically pleasing UI
helpful to visually distinguish one item from the
depicted in Figure 2. Things aren’t quite so cluttered
next in some subtle fashion. Otherwise, in the eyes
anymore.
of the user, it can be hard to tell where one item
ends and the next begins. Sufficient spacing is one
way to achieve this, but when the volume of data is
high and screen real estate is of high importance, an
alternating background color from one item to the
next is another common technique.
www.dotnetcurry.com/magazine 29
viable means of achieving alternating background </Style.Triggers>
colors? Not really. After all, how would we know </Style>
which Style to choose? Our view model would
need to expose its index within the list so that However, we now have a problem.
we could choose one Style for even indices and ContentPresenter is too primitive a control
another for odd indices. And what happens when to even expose a Background property. We’ll
we add or rearrange items in our list? Suddenly we come back to this issue shortly, but for now let’s
have to invalidate a whole bunch of items in order instead modify the item’s Margin based on the
for the UI to pick up the correct styles per item. AlternationIndex:
Obviously, such an approach would be awful.
<Trigger Property="ItemsControl.
AlternationIndex" Value="1">
Thankfully, ItemsControl provides the
<Setter Property="Margin" Value="12 3
AlternationCount and AlternationIndex 12 3"/>
properties to help us out of this predicament. </Trigger>
These two properties work in tandem:
AlternationCount allows us to specify how many
The result is shown in Figure 3 . The first thing
items to count before resetting AlternationIndex
you’ll notice is that I’ve added some more data to
back to zero, and AlternationIndex (an attached
make our changes easier to spot. Secondly, you’ll
property) tells us what index a certain item
see that every other item is indented further than
container has been assigned. For example, if we
the item preceding it (both from the left and the
set AlternationCount to 2 then the first item
right). Success!
will have AlternationIndex 0, the second item
will have AlternationIndex 1, and the third item
will have AlternationIndex 0 again. Repeat
ad nauseam for all items in our list. The upshot
of this is that our item containers now have an
AlternationIndex that we can use to trigger
different visuals.
<Trigger Property="ItemsControl.
AlternationIndex" Value="1">
<Setter Property="Background"
Value="LightGray"/>
</Trigger>
www.dotnetcurry.com/magazine 31
Phew! That wasn’t quite the smooth sailing we ItemsSource="{Binding
hoped for, but it’s worth re-iterating that we’re on a Source={StaticResource places}}"
lesser travelled path here. Using other controls that …
subclass ItemsControl will usually result in these Notice that we’re binding the ItemsSource
kinds of scenarios working more smoothly. property instead of simply assigning the
CollectionViewSource directly to it. That’s
because it is WPF’s binding infrastructure
Grouping Items
that recognizes the special role of
CollectionViewSource and interacts with it
When you bind an ItemsControl to a to obtain our data. In other words, the binding
collection as we have been thus far, things are infrastructure understands the indirection that
not entirely as they seem. Behind the scenes, CollectionViewSource provides, and it resolves
WPF is creating and binding to an adapter this indirection on our behalf.
called CollectionViewSource instead of
binding directly to the collection we give it. The With those two changes in place, our UI
CollectionViewSource that is created on our looks exactly as per Figure 5. But now what
behalf will point to the collection we supplied. This happens if we introduce some grouping to our
layer of indirection provides a suitable place where CollectionViewSource? To do so, we need to
grouping, sorting, and filtering of the underlying include one or more GroupDescription objects
data can occur. We’re not going to be discussing when creating the CollectionViewSource.
sorting and filtering in this article because they’re Often these will be instances of
entirely data concerns, but let’s take a look at how PropertyGroupDescription. For example, if we
we can group our data. were grouping by the Name property on our view
models (which might make sense with a lot more
The grouping functionality within the data), we could do this:
CollectionViewSource works in tandem with
grouping properties on the ItemsControl itself. <CollectionViewSource x:Key="places"
The CollectionViewSource decides how data is Source="{Binding}">
grouped whereas the ItemsControl decides how
<CollectionViewSource.
to render those groups.
GroupDescriptions>
<PropertyGroupDescription
Suppose we want to group our data by the type of PropertyName="Name"/>
place in question: all countries in one group, and </CollectionViewSource.
all cities in another. The first thing we need to do GroupDescriptions>
</CollectionViewSource>
is stop binding directly to our collection of places,
and instead bind to a CollectionViewSource.
There are various ways of achieving this, but we’ll Then items with the same name will appear
do it in XAML. As a first step, let’s explicitly declare a together (that is, if we had any with the same name).
CollectionViewSource in our Window resources: But this approach doesn’t help us in this scenario
because we want to group by the type of place, and
<CollectionViewSource x:Key="places" we have no appropriate property that gives us that
Source="{Binding}"/> information. Sure, we could add such a property, but
we’re going to instead demonstrate the flexibility
Notice how the Source property of the of the grouping infrastructure by sub-classing the
CollectionViewSource is bound to our abstract GroupDescription class:
underlying data collection. Now we need
to modify our ItemsSource to use this public sealed class
CollectionViewSource. The syntax for doing so PlaceTypeGroupDescription :
GroupDescription
is a little tricky:
{
public override object
<local:CustomItemsControl GroupNameFromItem(object item, int
<CollectionViewSource x:Key="places" This is all very empowering, but let’s just try and
Source="{Binding}"> display the name of each of our groups. We can
<CollectionViewSource. do that by adding this within our ItemsControl
GroupDescriptions> definition:
<local:PlaceTypeGroupDescription/> <local:CustomItemsControl.GroupStyle>
</CollectionViewSource. <GroupStyle>
GroupDescriptions> <GroupStyle.HeaderTemplate>
</CollectionViewSource> <DataTemplate>
<Border Padding="6"
Now when we run the application we see Figure Background="DarkSlateGray">
6. It’s an encouraging change: all our cities now <TextBlock
Text="{Binding Name}"
appear together at the top, followed by all countries
FontSize="14pt"
below them. But why is there nothing to visually
FontWeight="Bold"
demarcate each group? That’s because we haven’t Foreground="White"/>
supplied a GroupStyle. </Border>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</local:CustomItemsControl.GroupStyle>
www.dotnetcurry.com/magazine 33
We can take things a lot further with GroupStyle. Suppose, for example, we want to lay out our places
For example, by tweaking the ContainerStyle and horizontally rather than vertically. To achieve this,
HeaderTemplate, I was quickly able to come up we can write the following XAML:
with Figure 8. Of course, I chose a fresh palette and
<local:CustomItemsControl …>
tweaked the font as well, but you get the idea. <local:CustomItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation=
"Horizontal"/>
</ItemsPanelTemplate>
</local:CustomItemsControl.ItemsPanel>
…
<ItemsPanelTemplate>
<Canvas/>
</ItemsPanelTemplate>
www.dotnetcurry.com/magazine 35
</Setter.Value> That’s a significantly different visualization of the
</Setter> same data, but still utilizing an ItemsControl.
<Setter Property="Canvas.Top"> But what if we want the user to be able to select
<Setter.Value> a place? Looking through the properties of
<MultiBinding Converter=
"{StaticResource ItemsControl you may be disappointed to see
LatitudeConverter}"> nothing to help with selection. But that’s where
<Binding ElementName="image" ItemsControl subclasses come into play.
Path="ActualWidth"/>
<Binding ElementName="image"
Path="ActualHeight"/> ItemsControl Subclasses
<Binding Path="Latitude"/>
</MultiBinding> Having a firm grasp on all the ItemsControl
</Setter.Value>
concepts and features we’ve talked about thus
</Setter>
far will be invaluable when you need to utilize
other list-like controls. Many WPF controls –
Rather than going into the details of the converters,
ListBox, ComboBox, TabControl, TreeView,
I’ll leave it as an exercise for the reader to
Menu, StatusBar, and more – all inherit from
investigate how to convert longitudes and latitudes
ItemsControl. So in effect you already know how
to X and Y locations in a Mercator projection. It’s
to populate a Menu, modify the appearance of the
just some simple math.
StatusBar, or group items in a ListBox.
www.dotnetcurry.com/magazine 37
Scrolling such scenarios. In addition to that, they often enable
UI virtualization.
To illustrate this, take a look at Figure 14. On Figure 15: Enabling scrolling in ItemsControl via a custom
template
the left is an ItemsControl and on the right, a
ListBox. Both controls are bound to the same
data – a list of countries. Notice how the ListBox UI Virtualization
is scrollable (indeed, I have scrolled about a
third of the way through the list) whereas the The idea of UI virtualization, at least in the context
ItemsControl only shows the first 20 or so items of ItemsControl, is to pool and re-use item
with the rest out of view. containers. As the user scrolls through items, the
containers for those items that are moved out
of view can be re-used to host those that are
coming into view. This means the total number of
containers required to display the view is kept to a
minimum, , and less cruft is created for the garbage
collector to clean up.
We are now able to scroll through the items The ItemsControl is a real workhorse in WPF and
within the ItemsControl, per Figure 15. However, other XAML stacks. Its humble veneer could trick
subclasses of ItemsControl typically do this for us you into overlooking its power and flexibility. This
because they’re specifically designed to be used in two part article walked you through many aspects
kent boogaart
www.dotnetcurry.com/magazine 39
DIGGING DEEPER INTO
HIGH-TRUST APPS
IN SHAREPOINT
In one of the previous
articles, I wrote about
SharePoint
high-trust apps in Context Hurdles
SharePoint 2013. The
high-trust apps or server- The Visual Studio template for redirect URL with the app start URL
to-server apps (S2S) are SharePoint high-trust app, provisions and extra parameters such as the URL
SharePointContext.cs and of the host web, the URL of the app
intended to be installed
TokenHelper.cs files that hide all the web (if exists), SharePoint version and
on your SharePoint on- complexity of making the authorized navigation bar colour. The browser is
premises datacentre and calls to SharePoint. This is achieved then redirected to this long URL and
don’t require connectivity using a custom attribute in ASP.NET MVC the app uses the extra parameters in
to the Internet, unlike low- or Pre_Init page event in Web Forms the URL to figure out how to make the
trust or cloud SharePoint that inspects the current HTTP context, access token and to which SharePoint
apps such as those extracts the query string parameters endpoint should it make the CSOM
and then makes the app access token or REST call. Even if the SharePoint
available in the SharePoint
with this information. This SharePoint context instance is stored in the
Store. context is stored in the user session, so session, the URL parameters have to be
that it doesn’t have to be made again for present in every HTTP request as the
In this article I want to repeated requests to the app. SharePointContextProvider classes
go beyond the “Hello, check in the CheckRedirectionStatus
World” example and The standard app interaction flow method for their presence to validate
tackle some real-world implies that the user launches the app SharePoint contexts for every incoming
from SharePoint, clicking on the app request.
issues with high-trust app
icon. SharePoint then constructs the
development.
Once our app is loaded in the browser, what Imagine that instead of going to SharePoint for
happens when we click a link in the app that leads launching the app, we want to launch the app
to another page or another action? These extra via its URL. The app would open but without
parameters that SharePoint puts in the URL are the parameters it would be unable to connect to
gone. The standard solution in the Visual Studio SharePoint. However, the parameters are nothing
template is to use a JS script called spcontext. magic, just a couple of strings. We can store them
js that transparently appends these parameters in the web.config file, for example, and then use
in every application link, which is a very clumsy them as constants throughout the app code. As
approach in my opinion. high-trust apps run in our own SharePoint farm,
we can hardcode the URLs for both the host web
A better way would be to retrieve the parameters (SharePoint site where the app is installed) and
in the app landing page, store them somewhere the app web (automatically provisioned hidden
and then reuse them with no need to carry them SharePoint side for the app to store its data).
around. This requires fiddling with the standard They are known as soon as the app is installed
SharePointContext.cs and TokenHelper.cs. in SharePoint and we can copy them to our app
configuration file.
We can even completely dispense with the
parameters. How is this possible? In the normal In order to use this technique, we have to change
flow, it’s SharePoint that provides these parameters. the SharePointContext.cs file not to use any
But, it is not the only way. query strings but to use web.config provided
parameters.
www.dotnetcurry.com/magazine 41
Instead of calls to SharePointContext.
GetSPHostUrl we’ll call
Tokens and
WebConfigurationManager.
AppSettings["SpHostUrl"]. Also,
Non-Windows
in SharePointContextProvider. Authentication
CreateSharePointContext method we’ll
replace the query string parsing with the calls to The high-trust app access token is created by the
AppSettings keys. app itself. The app is responsible for inserting
the user ID in the context so that SharePoint can
Another nuisance with the out-of-the-box rehydrate the user in the CSOM call and check
TokenHelper.cs file is that it repeatedly queries permissions.
SharePoint in the GetRealmFromTargetUrl
method to obtain the SharePoint realm ID. This ID In the default implementation of TokenHelper
is a simple Guid and it is needed to make the app class, it is implied that the app runs with
access token. In Office 365 world, each SharePoint Windows authentication enabled, so the call
tenant has a unique realm ID, but in our SharePoint to WindowsIdentity class won’t return null.
farm, the entire farm is a single realm. Thus, we can However, with SharePoint, we aren’t limited to
also put the realm ID in our app configuration file using only Windows authentication. We can use
and skip the unnecessary realm checking altogether. the broader claims identity instead. As a matter of
fact, SharePoint 2013 uses claims authentication
To get the realm ID, just open a SharePoint by default and TokenHelper.cs class converts
PowerShell console and type Get- the Windows identity of the app user into a set
SPAuthenticationRealm. of claims that include the current Windows user’s
security identifier (SID).
www.dotnetcurry.com/magazine 43
Conclusion
edin kapic
@sravi_kiran @ekapic
@kent_boogaart @craigber
WRITE FOR US
@suprotimagarwal @saffronstroke
www.dotnetcurry.com/magazine 45
SOFTWARE GARDENING
OPEN
CLOSED
PRINCIPLE
Software Gardening: Seeds
Ugh. Sounds like Uncle Bob wants us to do the change the need for clients to change. You have to
impossible. Not only can we not change existing be careful here so that you don’t introduce bugs
code, but we can’t change the exe or dll files either. that affect the client. Good unit testing is critical.
Hang on. I’ll explain how this can be done.
Open for Extension
Closed for Modification
Having closed to modification out of the way,
Let’s drill into this principle, first by looking at we turn to open for extension. Originally, Meyers
closed for modification as this one is easier to discussed this in terms of implementation
discuss. In a nutshell, being closed for modification inheritance. Using this solution, you inherit a class
means you shouldn’t change the behavior of and all its behavior then override methods where
existing code. This ties in nicely with Single you want to change. This avoids changing the
Responsibility that I explained in my column in the original code and allows the class to do something
previous issue. If a class or method does one thing different.
and one thing only, the odds of having to change it
are very slim. Anyone that has tried to do much implementation
inheritance knows it has many pitfalls. Because
There are however, three ways you could change the of this many people have adopted the practice
behavior of existing code. interface inheritance. Using this methodology,
only method signatures are defined and the code
The first is to fix a bug. After all, the code is not for each method must be created each time the
functioning properly and should be fixed. You need interface is implemented. That’s the down side.
to be careful here as clients of the class may know However, the upside is greater and allows you to
about this bug and have taken steps to get around easily substitute one behavior for another. The
this. As an example, HP had a bug in some of their common example is a logging class based on an
printer drivers for many years. This bug caused ILogger interface. You then implement the class to
printing errors under Windows, and HP refused to log to the Windows Event Log or a text file. The
change it. Microsoft made changes in Word and client doesn’t know which implementation it’s using
other applications to get around this bug. nor does it care.
The second reason to modify existing code is to Another way to have a method open for extension
refactor the code so that it follows the other SOLID is through abstract methods. When inherited, an
principles. For example, the code may be working abstract method must be overridden. In other
perfectly but does too much, so you wish to refactor words, you are required to provide some type of
it to follow Single Responsibility. functionality.
Finally, a third way, which is somewhat controversial, Closely related to an abstract method is a virtual
is you are allowed to change the code if it doesn’t method. The difference is where you must override
www.dotnetcurry.com/magazine 47
the abstract method; you are not required to message)
override a virtual method. This allows a bit more {
flexibility to you as a developer. System.IO.File.WriteAllText(@"C:\
Users\Public\LogFolder\Errors.txt",
message);
There is one other, and often overlooked, way }
to provide additional functionality. That is the
extension method. While it doesn’t change the private void WriteEventLog(string
behavior of a method, it does allow you extend message)
the functionality of a class without changing the {
string source = "DNC Magazine";
original class code. string log = "Application";
public class ErrorLogger You may have missed another problem with this
{ code. It violates the Single Responsibility Principle.
private readonly string _whereToLog;
public ErrorLogger(string whereToLog)
{ Here’s the better way. While not fully feature
this._whereToLog = whereToLog. complete, this is a starting point.
ToUpper();
} public interface IErrorLogger
{
public void LogError(string message) void LogError(string message);
{ }
switch (_whereToLog)
{ public class TextFileErrorLogger :
case "TEXTFILE": IErrorLogger
WriteTextFile(message); {
break; public void LogError(string message)
case "EVENTLOG": {
WriteEventLog(message); System.IO.File.WriteAllText(@"C:\
break; Users\Public\LogFolder\Errors.txt",
default: message);
throw new Exception("Unable to }
log error"); }
}
} public class EventLogErrorLogger :
IErrorLogger
private void WriteTextFile(string {
www.dotnetcurry.com/magazine 49
Building a
Sound Cloud
Music Player in
Windows 10
Microsoft's vision of apps that can be written once
and will run on a wide variety of devices, is finally a
reality with the release of Windows 10. The single,
unified Windows core enables one app to run on
every Windows device – be it a phone, a tablet, a
laptop, a PC, or the Xbox console. And very soon the
same apps will also run on the upcoming devices
being added to the Windows family, including IoT
devices like the Raspberry Pi 2, Microsoft HoloLens
and the Surface Hub.
First Look
We are going to develop a Music Player in Windows
10 which will use Sound Cloud API to play our Likes,
Playlists etc. Here is a screenshot of how the player
will look in Desktop, Tablet and Phone.
If you do not use Sound Cloud (there is no reason
not to use Sound Cloud if you love Music), register Shell
for a new account and start Liking tracks and create
playlists for your favourite tracks. We will be using One of the new controls introduced in Windows 10
these for our App. is the SplitView. It is a very simple but useful control
which can be used to build quick Navigation related
Register a new Client Application by visiting the features in our App. This control is also very flexible
Sound Cloud Developer Website (https://developers. in terms of customization and presents unique
soundcloud.com/). Keep a note of the Client Id experiences across different devices.
Value.
We will change the new project to use a Custom
Page that will hold the SplitView control and this
Project page will act as the shell for the whole app giving it
a Single Page App like experience.
Fire up Visual Studio 2015 and create a New Blank
App (Universal Windows) under Templates > Visual - Add a Blank Page by Right Clicking the Project
C# > Windows. Right click the new project and click > Add > New Item. Name this new Page as
on Manage NuGet Packages. Search for Newtonsoft. AppShell.xaml
json library and install the package. You may also
want to add some images that are included with the - Add the following xaml code to AppShell.xaml
Source Code of this article. We will be using those
to design the App. <Page.Resources>
<DataTemplate
If you want to learn more about new Controls in x:Key="NavMenuItemTemplate"
Windows 10, I would recommend downloading x:DataType="local:NavMenuItem" >
<Grid>
Developer Samples from GitHub (https://github. <Grid.ColumnDefinitions>
com/Microsoft/Windows-universal-samples) and <ColumnDefinition Width="48" />
playing around with the sample projects. <ColumnDefinition />
</Grid.ColumnDefinitions>
www.dotnetcurry.com/magazine 51
<FontIcon x:Name="Glyph" Margin="0,48,0,0"
FontSize="16" Glyph="{x:Bind ItemContainerStyle="{StaticResource
SymbolAsChar}" NavMenuItemContainerStyle}"
VerticalAlignment="Center" ItemTemplate="{StaticResource
HorizontalAlignment="Center" NavMenuItemTemplate}"
ToolTipService.ToolTip="{x:Bind ItemInvoked=
Label}"/> "NavMenuList_ItemInvoked" >
</controls:NavMenuListView>
<TextBlock x:Name="Text" Grid. </Grid>
Column="1" Text="{x:Bind Label}" />
</Grid> </SplitView.Pane>
</DataTemplate>
</Page.Resources> <Frame x:Name="frame"
x:FieldModifier="Public">
<Grid Background="#273140"> <Frame.ContentTransitions>
<!-- Adaptive triggers --> <TransitionCollection>
<VisualStateManager.VisualStateGroups> <NavigationThemeTransition>
<VisualStateGroup> <NavigationThemeTransition.
<VisualState> DefaultNavigationTransitionInfo>
<VisualState.StateTriggers> <EntranceNavigationTransitionInfo/>
<AdaptiveTrigger </NavigationThemeTransition.
MinWindowWidth="720" /> DefaultNavigationTransitionInfo>
</VisualState.StateTriggers> </NavigationThemeTransition>
<VisualState.Setters> </TransitionCollection>
<Setter Target="RootSplitView. </Frame.ContentTransitions>
DisplayMode" Value="CompactInline"/> </Frame>
<Setter Target="RootSplitView. </SplitView>
IsPaneOpen" Value="True"/>
</VisualState.Setters> <ToggleButton x:Name="TogglePaneButton"
</VisualState> Style="{StaticResource
<VisualState> SplitViewTogglePaneButtonStyle}"
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/> IsChecked="{Binding IsPaneOpen,
</VisualState.StateTriggers> ElementName=RootSplitView, Mode=TwoWay}"
<VisualState.Setters>
<Setter Target="RootSplitView. AutomationProperties.Name="Menu"
DisplayMode" Value="Overlay"/> ToolTipService.ToolTip="Menu"/>
</VisualState.Setters>
</VisualState> <MediaElement x:FieldModifier="Public"
</VisualStateGroup> AudioCategory="BackgroundCapableMedia"
</VisualStateManager.VisualStateGroups> x:Name="mPlayer"
RequestedTheme="Default"
<!-- Top-level navigation menu + app CompositeMode="MinBlend"/>
content --> </Grid>
<SplitView x:Name="RootSplitView"
DisplayMode="Inline" In the above code, we have added the following:
OpenPaneLength="256"
IsTabStop="False"
Background="#273140" 1. SplitView control (RootSplitView) which has a
> custom Navigation control (NavMenuList) in its Pane
<SplitView.Pane> and a Frame (frame) which will hold our Pages.
<Grid Background="#273140">
<!-- A custom ListView to display the
items in the pane. --> 2. ToggleButton (TogglePaneButton) which will be
the Hamburger menu button.
<controls:NavMenuListView
x:Name="NavMenuList" 3. Data template for binding items for the custom
Background="#273140"
TabIndex="3" Navigation Control.
www.dotnetcurry.com/magazine 53
{ <VisualState x:Name="PointerOver">
this.AppFrame.Navigate(item. <Storyboard>
DestPage, item.Arguments); ...
} </Storyboard>
} </VisualState>
} <VisualState x:Name="Pressed">
<Storyboard>
private void Page_Loaded(object ...
sender, RoutedEventArgs e) </Storyboard>
{ </VisualState>
((Page)sender).Focus(FocusState. <VisualState x:Name="Disabled">
Programmatic); <Storyboard>
((Page)sender).Loaded -= Page_Loaded; ...
} </Storyboard>
} </VisualState>
<VisualState x:Name="Checked"/>
In the above code, we do the following <VisualState x:Name=
"CheckedPointerOver">
<Storyboard>
1. We create a new List of objects of NavMenuItem ...
class and populate it with required menu options </Storyboard>
and suitable icons. </VisualState>
<VisualState x:Name=
"CheckedPressed">
2. We also add an Item Invoked event handler to <Storyboard>
handle click events and navigate to subpages. ...
</Storyboard>
- If you notice, we are using some custom styles </VisualState>
<VisualState x:Name=
for our controls and we will use a common styles "CheckedDisabled">
page to hold these style templates. Add a new <Storyboard>
folder to the Project named Styles and add a new ...
Resource Dictionary file and name it Styles.xaml. Add </Storyboard>
the following code to the newly created file (code </VisualState>
truncated for brevity. Check the source code) </VisualStateGroup>
</VisualStateManager.
VisualStateGroups>
<Style
x:Key="SplitViewTogglePaneButtonStyle" <ContentPresenter x:Name=
TargetType="ToggleButton"> "ContentPresenter"
<Setter Property="FontSize" Value="20" Content="{TemplateBinding Content}"
/> Margin="{TemplateBinding Padding}"
<Setter Property="FontFamily" HorizontalAlignment=
Value="{ThemeResource "{TemplateBinding
SymbolThemeFontFamily}" /> HorizontalContentAlignment}"
...
<Setter Property= VerticalAlignment
"UseSystemFocusVisuals" Value="True"/> ="{TemplateBinding
<Setter Property="Template"> VerticalContentAlignment}"
<Setter.Value> AutomationProperties.
<ControlTemplate AccessibilityView="Raw" />
TargetType="ToggleButton"> </Grid>
<Grid Background="{TemplateBinding </ControlTemplate>
Background}" x:Name="LayoutRoot"> </Setter.Value>
<VisualStateManager. </Setter>
VisualStateGroups> </Style>
<VisualStateGroup x:Name= <Style x:Key="PageTitleTextBlockStyle"
"CommonStates"> TargetType="TextBlock"
<VisualState x:Name="Normal" /> BasedOn="{StaticResource
www.dotnetcurry.com/magazine 55
We will be using Json.NET which is a high
performance, popular JSON framework to serialize Landing Page
and deserialize Sound Cloud objects from Sound
Cloud website and custom Sound Cloud objects in We will use MainPage.xaml as the landing page for
our App. I used the website http://json2csharp.com/ our app which will handle login and navigate to
to quickly create classes (and modified for our app) subsequent pages.
for Sound Cloud objects that we will be adding in
our next step. - Add the following code to MainPage.xaml .
- Add the following new class files to our project <Grid Background="#edf3fb">
<StackPanel VerticalAlignment="Center">
o SoundCloudTrack.cs <ProgressRing x:Name="loginProgress"
HorizontalAlignment="Center"
IsActive="True" Foreground="#273140"
public class SoundCloudTrack{ />
public int id { get; set; }
public string created_at { get; set; } <TextBlock HorizontalAlignment="Center"
public int user_id { get; set; } Text="Please wait..."
public int duration { get; set; } Style="{StaticResource
... SubtitleTextBlockStyle}"
public SoundCloudUser user { get; set; Foreground="#273140"/>
} </StackPanel>
... </Grid>
public SoundCloudCreatedWith created_
with { get; set; } In the above code we add a ProgressRing control
public string attachments_uri { get; and TextBlock to show the progress.
set; }
}
- Add the following code to MainPage.xaml.cs
o SoundCloudCreatedWith.cs
using Newtonsoft.Json;
public class SoundCloudCreatedWith ...
{
public int id { get; set; } // The Blank Page item template is
public string name { get; set; } documented at http://go.microsoft.com/
public string uri { get; set; } fwlink/?LinkId=402352&clcid=0x409
public string permalink_url { get;
set;} namespace MusicPlayer
} {
/// <summary>
o SoundCloudUser.cs /// An empty page that can be used on
its own or navigated to within a Frame.
/// </summary>
public class SoundCloudUser public sealed partial class MainPage :
{ Page
public int id { get; set; } {
public string permalink { get; set; } public MainPage()
public string username { get; set; } {
public string uri { get; set; } this.InitializeComponent();
public string permalink_url { get;
set; } this.Loaded += MainPage_Loaded;
public string avatar_url { get; set; } }
}
private void MainPage_Loaded(object
sender, RoutedEventArgs e)
{
loginProgress.IsActive = false;
www.dotnetcurry.com/magazine 57
- We also navigate to a new page called NowPlaying Rect="0,0,500,250"
which we will add in our next step. x:Name="AlbumartClip"/>
</Ellipse.Clip>
</Ellipse>
Now Playing <!-- Bottom part of album art with
controls -->
Add a new Blank Page to our project and name it <Ellipse Height="500"
NowPlaying.xaml. Add the following xaml code to Grid.Row="0" Width="500"
the page. x:Name="AlbumartContainerDown"
Fill="#34353c" >
<Ellipse.Clip >
<Grid Background="#edf3fb"> <RectangleGeometry
<!-- Adaptive triggers --> x:Name="AlbumartContainerDownClip"
<VisualStateManager.VisualStateGroups> Rect="0,250,500,500" />
<VisualStateGroup> </Ellipse.Clip>
<VisualState> </Ellipse>
<VisualState.StateTriggers>
<AdaptiveTrigger <TextBlock x:Name="txtSongTitle" Grid.
MinWindowWidth="720" /> Row="0" HorizontalAlignment="Center"
</VisualState.StateTriggers> Text="Song Title "
<VisualState.Setters> FontSize="25" Foreground="White"
... Style="{StaticResource
</VisualState.Setters> HeaderTextBlockStyle}"
</VisualState> TextTrimming="WordEllipsis" />
<VisualState>
<VisualState.StateTriggers> <TextBlock x:Name="txtAlbumTitle"
<AdaptiveTrigger MinWindowWidth="0" Grid.Row="0" Text="Label "
/> HorizontalAlignment="Center"
</VisualState.StateTriggers> FontWeight="Light" FontSize="20"
<VisualState.Setters> Foreground="#9799a5"
... Style="{StaticResource
</VisualState.Setters> BodyTextBlockStyle}"
</VisualState> TextTrimming="WordEllipsis"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups> <StackPanel Margin="0,350,0,0"
<Image Source="Assets/BG.png" x:Name="ControlContainer" Grid.
Stretch="Fill"/> Row="0" Orientation="Horizontal"
VerticalAlignment="Top"
<Grid VerticalAlignment="Center"> HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <Button x:Name="btnPrev"
</Grid.RowDefinitions> Background="Transparent" Height="80"
<!-- Black ring around Album art with Width="80" Click="btnPrev_Click">
opacity .10 --> <Image Source="Assets/Prev.png"
<Ellipse Height="525" Grid.Row="0" Stretch="Uniform"/>
Width="525" Fill="Black" </Button>
Opacity=".10" x:Name="AlbumartRing"/>
<Button x:Name="btnPlay"
<!-- Album Art --> Background="Transparent" Height="120"
<Ellipse Height="500" Grid.Row="0" Width="120" Click="btnPlay_Click">
Width="500" x:Name="Albumart" > <Image Source="Assets/Play.png"
<Ellipse.Fill> Stretch="Uniform"/>
<ImageBrush x:Name="albumrtImage" </Button>
ImageSource="Assets\Albumart.png"
Stretch="UniformToFill" /> <Button x:Name="btnNext"
</Ellipse.Fill> Background="Transparent" Height="80"
<Ellipse.Clip > Width="80" Click="btnNext_Click">
<RectangleGeometry <Image Source="Assets/Next.png"
www.dotnetcurry.com/magazine 59
private void btnNext_Click(object
sender, RoutedEventArgs e)
{
App.nowplayingTrackId += 1;
if (App.nowplayingTrackId >= App.
nowPlaying.Count)
{
App.nowplayingTrackId = 0;
}
www.dotnetcurry.com/magazine 63
• You need multiple builds to run for your account
www.dotnetcurry.com/magazine 65
8. There are two triggers available - Continuous Integration and We can add tags to the build so that we can filter
Scheduled. the builds later. We can also find out the changeset
which triggered the build as well as retain any build
indefinitely if needed. At the time of build execution
the console will show us live results as shown in
Figure 14.
gouri sohoni
www.dotnetcurry.com/magazine 67
l l o . j s
d H e
y a n
u e r e d i a
g p , j Q a l M
Usin
t s t ra S o c i
B o o rat e s
i nt e g s i t e
t o W e b
y o u r
in
which, one can view or
post updates via an app or,
another site. The app or,
of the social presence site using social media has
of the company or, the to be authenticated and
what to surf on the individual. should have enough rights
internet unless we to do so. For this, the site
The web is check one of the social More consumers are should be authenticated
fundamentally about media sites. Most of connected than ever via OAuth and use the
people and the huge the corporations use before, and if you are OAuth token for each
popularity of Social social media to post not engaging with them interaction. Handling the
Media has echoed this their news, updates via social media, you are task of authentication
notion. Social media is and even for important wasting an opportunity. and making sure to send
one of the must go-to announcements. Social the security details on
places for everybody media integration on Every social media site each interaction is made
who surfs online. At websites also gives the like Twitter, Facebook possible via libraries like
times, we can’t decide viewer an impression etc. provides APIs using hello.js .
www.dotnetcurry.com/magazine 69
creating an account with the provider. The Provider
verifies the account credentials, then it matches
the Application Key and provides a token back to
the Relying Party with which only the Authorized
actions can be performed.
With OAuth knowledge under our belt, we will write Visual Studio automatically provides a local
code that allows us to connect to three social media server to host our website. This is a necessary step
sites - Twitter, Facebook and Instagram using only because, as stated previously, OAuth is a dialogue
JavaScript . between two servers.
To help us with this objective, we’ll use a very useful Now that our local server is setup, we can create our
library from Andrew Dodson called Hello.js (http:// OAuth clients on Twitter, Facebook and Instagram.
adodson.com/hello.js/). Normally these actions can be performed in the
“Developer” section of many social media sites.
For Facebook:
1. Go to http://developer.facebook.com
3. Hit “Register a New Client” Here add some basic information like “Application
Name” and “Description” and some important
Here add some basic information like “Application data like the “Site URL”. Fill these details with our
Name” and “Description” and some important data website data as follows:
like the “Website URL” and “Redirect URI(s)”. Fill
these details with our website data as shown here:
www.dotnetcurry.com/magazine 71
For OAuth1 or OAuth2 authentication with explicit src="https://cdnjs.cloudflare.com/ajax/
grant services like Twitter, we need to use an OAuth libs/masonry/3.3.1/masonry.pkgd.min.
Proxy service exposed by Hello.js. js"></script>
<script type="text/javascript"
For Hello.js proxy registration: src="jQuery.socialmedia.js"></script>
<link href="jQuery.socialmedia.css"
rel="stylesheet" />
Plugin initialization
Data displaying
The following script runs in the document.ready()
Let us create a new page called Plugin.html event on the “#connect” button click event handler
that will include all necessary plugins and add and fills the div “mySocialMedia” with user profile
references to some JavaScript and CSS code. In the information coming from Twitter, Instagram and
<head> section, add the following reference: Facebook.
www.dotnetcurry.com/magazine 73
// Facebook connection handler var d3 = $.Deferred();
setTimeout(function () {
connectToFacebook($facebookEl); }, // Waiting for the deferred completion
2000); $.when(d1, d2, d3).done(function (v1,
} v2, v3) {
} // Build one concatenated array with
the result of each data fetch result
Now that we are logged in to our favorite social
fecthedData = fecthedData.concat(v1);
media sites, the next step is to fetch our feeds from fecthedData = fecthedData.concat(v2);
these socials! fecthedData = fecthedData.concat(v3);
The script we will see shortly runs in // Render the mixed fetched data
document.ready() event on the “#fetch” button click renderFetchedData(_$this, fecthedData);
});
event handler and fills the div “mySocialMedia” with
data fetched from Twitter, Instagram and Facebook. fetchTwitterData(_opts.twitter, d1);
fetchInstagramData(_opts.instagram,
The fetch method uses Hello.js in order to simplify d2);
all the OAuth request to each social site, with some fetchFacebookData(_opts.facebook, d3);
}
very simple API’s.
Since we are logged in to Twitter in the Init() code,
For demo purposes, all the data fetched from the if twitter integration is enabled in the plugin
socials are added in an array, shuffled and displayed initialization, we get its instance and fetch data
in a responsive grid system using Masonry (http:// from twitter. The fetch is done using Hello.js that
masonry.desandro.com/) from David DeSandro. simplifies this operation. The core functionality of
the app requests twitter for the 50 latest tweets
Let’s see the plugin code. Inside the fetch() function (or a number you chose) and loads them in the
of the plugin, we can see the Hello.js and Masonry “tweet” array. When the data fetch is completed, the
integration. Since each response from the socials deferred object “resolve” method is called and the
is asynchronous, we will use jQuery’s deferred API. operation continues.
Deferred is an important concept and if you are
not familiar with it, check: https://api.jquery.com/ function fetchTwitterData(o, d) {
jquery.deferred/ and http://www.dotnetcurry.com/
jquery/1022/jquery-ajax-deferred-promises if (!o.enabled) {
d.resolve([]);
return;
The code sends request to each social and concats }
and shuffles the response inside an array. The social
data fetch code shown here is only for Twitter, // Twitter instance
however the complete code will contain details for var twitter = hello('twitter');
all the three social media sites we are connecting
twitter.api('twitter:/me/share', {
to.
limit: o.maxElements }, function (r) {
var tweets = [];
First we will create three Deferred objects and on for (var i = 0; i < r.data.length;
completion, call the rendering function inside the i++) {
main div. var o = r.data[i];
tweets.push({ social: 'twitter',
text: o.text });
// Deferred objects };
var d1 = $.Deferred(); d.resolve(tweets);
var d2 = $.Deferred(); });
}
Conclusion
Irvin Dominin
www.dotnetcurry.com/magazine 75
Using new XAML tools in
Visual Studio 2015
With an increase in XAML based apps Seamless Integration with Blend
for Windows Phone, Windows 8+ and
Universal apps, developers have been
Application development in XAML needs efforts
demanding new features for XAML in the
from both UI Designer and Developer. In the
areas of memory and CPU profiling, UI
development process, the UI Designer uses Blend to
debugging, seamless integration between
manage XAML design using design templates, styles,
Visual Studio and Blend. The latest
animations etc. Similarly the UI Developer uses
release of Visual Studio 2015 provides
Visual Studio to add functionality to the design.
some new XAML development features for
Many-a-times it is possible that the UI Designer
applications. In this article, we will take an
and Developer work on the same XAML file. In this
overview of some of these new features.
case, the file updated by the designer or developer
should be reloaded by the IDE (Blend and Visual
Studio) each time. Visual Studio 2015 contains new
settings that allows the integration of the two IDEs
to be seamless. Let’s explore this setting.
www.dotnetcurry.com/magazine 77
• to see the visual tree with dynamically generated {
UI Elements based on the DataBinding, Styles, etc. Add(new Employee() { EmpNo = 1,
EmpName="A"});
Add(new Employee() { EmpNo = 2,
• to identify the critical sections of the generated EmpName = "B" });
Visual Tree which result in performance Add(new Employee() { EmpNo = 3,
degradation. EmpName = "C" });
Add(new Employee() { EmpNo = 4,
Step 1: Open MainWindow.xaml and update the EmpName = "D" });
Add(new Employee() { EmpNo = 5,
XAML as shown in the following code: EmpName = "E" });
}
<Grid Height="346" Width="520"> }
<Grid.RowDefinitions>
<RowDefinition Height="300"> The above code defines the Employee class with
</RowDefinition>
<RowDefinition Height="40"> Employee properties and EmployeeList class
</RowDefinition> containing Employee Data. On the click event of the
</Grid.RowDefinitions> button, the EmployeeList is passed to ItemsSource
<DataGrid Name="dgemp" property of the DataGrid.
AutoGenerateColumns="True" Grid.
Row="0"/>
<Button Name="btn" Content="Click" Step 3: Run the Application. A WPF window will be
Height="30" Width="230" displayed with Live Visual Tree panel as shown in
Click="btn_ Click" Grid.Row="1" the following diagram:
Background="Red"></Button>
</Grid>
www.dotnetcurry.com/magazine 79
empTemplate can be shown:
DataBinding Debugging
The above diagram shows the record selected About the Author
from the ListBox (Red outline). On the right side of
the diagram see the Live Property Explorer with
Mahesh Sabnis is a Microsoft MVP
the DataContext values. This is a cool feature for in .NET. He is also a Microsoft
developers working on the LOB applications using Certified Trainer (MCT) since
XAML. 2005 and has conducted various
Corporate Training programs for .NET
Technologies (all versions). Follow
Defining Regions in XAML him on twitter @maheshdotnet
While working with C# or VB.NET code in Visual Mahesh blogs regularly on .NET
Studio, we can make use of Region-EndRegion Server-side & other client-side
www.dotnetcurry.com/magazine 81