Visual Studio "14" CTP

[原文发表地址] http://blogs.msdn.com/b/somasegar/archive/2014/06/03/first-preview-of-visual-studio-quot-14-quot-available-now.aspx

[原文发表时间] 2014-6-3 11:55 AM

今天,我们开始为下一个版本的Visual Studio提供首次社区技术预览版。代号为Visual Studio”14″。这个早期版本关注于收集客户反馈和来自Visual Studio 社区的测试结果。“Visual
Studio”14″很有可能会在2015年后半年发布,到时候会是一个完整的预览版本,还会有最终的命名。考虑到这是一个非常早期的版本,请在没有安装的Visual Studio 的早期版本的测试环境中安装此版本。

你可以阅读有关此次Visual Studio”14”CTI 的新功能和已知问题,还可以下载这个版本的Visual Studio。

过去 3 个月,我们宣布了VisualStudio”14”中许多令人兴奋的重要技术,包括“Roslyn.Net编译器,ASP.NETvNext Apache Cordova工具。Visual Studio”14″CTP 1 包括这几个工具中的一部分,以及许多在Visual Studio的其他方面的改进,包括可以提早看到一些将会成为Visual Studio”14″的一部分C++11的新功能。

C# and VB .Net 编辑器平台(“Roslyn”)

在Visual Studio14 中,C#,VB编译器和IDE支持统一的.Net 编译平台(”Roslyn”)。这个开源编译器就像Visual Studio”14″中的数十开发人员后的服务支持一样。强大的构建能力,智能感知,CodeLens,调试和很多其他开发者每天都用到的功能。在整个开发体验中,大多数体验是不变的,但也有许多编译器平台的的小小改进。

在 Visual Studio”14″预览版中,C#支持重构已经彻底更新,其中包括两个新的核心重构:内联临时变量、 介绍解释变量。此外,支持Visual Basic的重构也被首次添加到Visual Studio”14″预览版中。

Visual Studio “14″也支持自带分析器的NuGet APIs, 可以解析在敲代码时遇到的问题,为您提供自动修复功能, 所有这些都有.net 编译平台驱动。

你可以在C#博客Visualbasic博客中阅读更多关于C#和VB的新开发体验。

ASP.NET vNext

几周前,我们宣布了 asp.net Vnext 和计划未来在服务器端的.net。ASP.NET vNext 专为云端和服务器端提供 SxS 安装选项,通过模块化,高度可配置框架和web 协议栈显著提高了开发人员效率。

Visual Studio”14″CTP 优先提供了Asp.net vNext 工具开发体验的提前预览,包括Asp.NET4.5 应用程序模板,以及针对ASP.NET vNext的一些新的模板。

 

下个版本的.Net, 将会随着Visual Studio”14″的下个版本一起,包含ASP.Net vNext,和我们在近几个月看到的许多新的,net 技术一起。有用于Windows Store 新的.Net Native,下一代JIT和Roslyn编译器。

可以在Net Web 开发和工具的博客中阅读更多关于Visual Studio14 和ASP.NET vNext 的信息。

C++ 11/14

我们继续推进Visual c + + 编译器标准的一致性。Visual Studio”14″CTP 包括支持用户定义的文本、 noexcept、 alignof 和 alignas,继承C++11 中的构造器, 生成的lambda 表达式,函数返回类型的自动推断,C++14 中通用的lambda表达式和更多C++ 的新功能。

我们延续着我们去年对C++11 C++14制定的标准一致路线。下图更新了我们现在知道的和我们正在做的未来Visual Studio “14″ CTPs中的特性。

此外,Visual Studio”14″CTP 包括调试、类库和 IDE 的新功能。

你可以在C++博客上阅读关于C++在Visual Studio “14″ CTP中的改进。

总结

这个早期预览版的Visual Studio “14″ 提供了收集下一个版本的Visual Studio 和.NET反馈的机会。对于尝试这个CTP的开发者,我鼓励大家把自己的反馈分享在连接网站上,或者通过在Visual Studio IDE上发送一个微笑

Namaste!

Does psychology explain why people are upset about NSA spying?

8 months ago, I wrote a blog post about how I am more concerned about being hacked by malicious spammers than I am about being spied upon by the NSA. In the year since Snowden, my views haven’t changed much. I understand that it’s a concern but I am more-or-less ambivalent about it [1].

I understand that there is a very vocal segment that protests this invasion of privacy vehemently, but I just can’t get worked up about it.

Why am I so different from this vocal segment? And why does this vocal segment care so much?

The Principle of Scarcity

To answer this, I recently read the book “Influence: The Psychology of Persuasion” by Robert Cialdini. In it, psychologist Robert Cialdini describes six outlining principles about how to persuade people – principles that have proven themselves over and over again. These are not self-help theories but instead theories that have been tested by science.

image

One of the topics of the book is the Principle of Scarcity. People view potential losses as more impactful than potential gains. This is universally true, we are more concerned about losing something than we are about winning.

Here’s proof. What would you rather have:

  1. Option 1 – A 10% chance of winning $1 million, or
  2. Option 2 – A 100% chance of winning $90,000

?

If you’re like most people, you probably go with Option 2. However, if you do the math on the expected payout, you multiply the chance of winning by the amount you would win to get the expected winnings. Option 1 has an expected winning of $100,000 (10% x $1,000,000) while Option 2 is $90,000, less than Option 1.

But most of us want to go with the sure thing of Option 2 even though it is less because it is too psychologically painful for us to “lose” the sure thing of $90,000 compared to the mere possibility of $1 million, even if you know the probabilities.

Even if you personally, reading this right now, say to yourself “Well, I know the math. I would certainly go with Option 1” you still have to fight your natural instincts to do this because it feels wrong and you don’t like doing it. Thus, while you may understand the math in this case, be very sure you won’t understand the math in every case, nor in every real world circumstance with deals with the Principle of Scarcity.


The Increasing Value of Time

Another example is the phrase “If it weren’t for the last minute, nothing would ever get done.” This is our tendency to put things off until there is very little time left and then scrambling to complete it. This is known as “hyperbolic discounting.” What is happening is that we, as humans, are not good at anticipating the future but as a deadline becomes nearer and near – and time-to-complete becomes correspondingly more scarce – the value of the thing we are putting off becomes more urgent as the remaining time becomes much more valuable.

image

Scarcity is increasing value of something.

As opportunities become more scarce, we desire more freedom, and we hate losing the freedoms we already had.

This goes one step further – it is not just a matter of scarcity that makes something that is more desirable, but instead a drop from abundance to scarcity that makes it much more powerful than constant scarcity.

For example, when governments ban books, it is then that people want to read them. And to add to the intensity, if the drop in abundance is because others want the scarce resource, this increases the desirability.

How it Works in Humans

Researchers have tested this – they had volunteers come in and answer some questions and then leave, but on the way out there was a plate of cookies. When there were plenty of cookies, people rated the cookies’ taste as fine. But when there was only a couple of cookies and plenty of crumbs (indicating that there had been a lot of them previously but others had depleted the stock), people rated them even more highly.

image

This principle of scarcity is hard-wired into our brains.

So what does this have to do with NSA spying?

Here’s what I think – the scarce resource that we thought we had was privacy. Privacy is valuable and we believed that nobody was looking over our shoulder. Who wants the government spying on them? Nobody, that’s who.

However, when the NSA scandal broke, suddenly this resource/freedom we thought we had was virtually non-existent. And we hate losing freedoms we had before. The fact that it was previously abundant due to encryption, and is scarce now (due to government circumventing it) made it that much worse.

And making it even worse is that government wants our privacy! Thus, someone else is stealing something that was ours and that’s what makes it scarce!

And I think that’s why people are so upset – because of the Principle of Scarcity and how we’re hard wired to react to it.

The Roots of the Desire for Privacy

Okay, so maybe we’re hard-wired to react to scarcity. And maybe we’re a little upset because we lost our freedom of privacy.

But why should we even care about privacy at all?

I think it’s because we don’t like being watched. There’s a myth that says that public speaking is our number one fear. Studies are conflicted about this, but it is one of the things that people are afraid of and it ranks very highly, higher than things we should be more afraid of like disease, car accidents, or violence.

So why are we even afraid of public speaking to begin with?

image

I think it’s hard wired into our brains because we don’t like to be watched. For you see, for hundreds of thousands of years, even millions of years, our ancestors wandered around on the African savannah, looking for game but also just trying to survive. Our ancestors had to work in groups and we would sometimes stalk our game for days or even weeks at a time.

image

However, humans are not particularly good fighters against any other animal without our tools or the groups of people we hunt with (i.e., working together). While we would hunt other animals, other animals would hunt us. And when they hunted us, they would secretly stare at us first, sizing us up before pouncing.

Eventually, we developed biases in us to dislike being watched because it meant that if we were, we could soon become the prey and would fail to pass on our genetic material. Natural selection favored genes that selected for being aware of being watched and taking steps to correct for it.

We don’t like to be watched without our permission because we have genes that have selected for this personality trait.

Your Brain is not a Lawyer

We sometimes think of ourselves as rational creatures. We have a model of ourselves where our brains are basically like Prosecuting Attorneys and Judges. The prosecuting attorney presents the evidence, the judge weighs it, and then issues a decision. In this way, we are mostly logical creatures; sure, we sometimes make mistakes but for the most part we act in our own best interest.

image

 

This was the view before the 1960’s and the rise of modern psychology, and the 1990’s before the rise of behavioral psychology. Not only do we now know that we make cognitive errors all the time but that we are predictably irrational.

Your brain is not an attorney/judge combination that weighs the evidence and makes a careful decision. That happens occasionally but it is not the norm. Instead, you have a limbic system which is the system that reacts and drives your emotions, and a neo-cortex which is the thinking and reasoning part of your brain. And these two are always working together, and sometimes they are conflicting.

We like to think that the logical side wins out over the “emotional” one (the limbic system is far more complex than what I described). What happens in reality is that most of the time, our limbic system has an emotional response to a stimulus (a physical feeling, or a sound, or an idea) and then our neo-cortex brain works to rationalize why we feel the way we feel.

If you ask a person why they took the $90,000 sure thing instead of the $100,000 expected payout (10% chance of $1 million), they may say something like “I can use the $90,000 today and the chances of getting $1 million aren’t worth the risk of losing it.” And that’s close to reality; our limbic brains tell us “Don’t lose the sure thing!” and then our neo-cortexes get on with the work of making up a reason why we are doing the irrational thing.

 

Putting it All Together

This is why I think (some) people hate the NSA spying scandal so much. We have justified it as they are over-collecting data and it could lead to abuse. While I think that’s possible, I think the disliking of it is because we don’t like being secretly watched by someone. Not being watched by someone is called “privacy” and we hate losing the freedoms we had (or thought we had), and that includes privacy. While we have reasons for disliking it, we come up with these after the fact; we don’t weigh the pros and cons and come to a decision. Instead, we come to a decision and then weigh the pros and cons.[3]

That’s why I think some people are so vocal about NSA spying.

So what about people who don’t seem to react so strongly? I will get to that in a future post.


[1] 10 weeks ago, I had braces put onto my teeth. I’ve never had them done before, that is, I didn’t have them as a kid [2]. Let me tell you, I experience way more angst up to and during that procedure than I ever had thinking about how the NSA might be spying on me.

[2] I’ve needed this procedure for at least a decade. I finally broke down and consented to wearing them for two years.

[3] Yes, this is oversimplified. As it turns out, there are good reasons for being against government over-collection of data just as there are good reasons for there to be a government that runs society.

Azure WebSites ? WordPress ????????????????????

このポストは、8 月 20 日に投稿した WordPress Troubleshooting Techniques on Azure Websites の翻訳です。

WordPress は Azure WebSites ギャラリーで提供されている一般的な Web アプリケーションの 1 つで、動的な Web サイトの構築に使用します。WordPress サイトを運用していると、何らかの問題が発生しトラブルシューティングを行う機会があるかと思いますが、この記事ではよくある問題について説明し、その対策をご紹介します。

自分の WordPress サイトで php.ini の構成を更新する方法

ユーザーに許可するファイル アップロード時の最大サイズを規定の 8 MB から 12 MB に変更するなど、アプリケーションの要件に応じて WordPress サイトの php.ini ファイルの変更が必要となる場合があります。

ユーザーが PHP の構成を定義する場合は、サイトのルート (D:homesitewwwroot) で .user.ini という名前のファイルを作成して、次の文を追加します。

upload_max_filesize = 12M

その後、Web サイトを再起動します。変更が上書きされたことを確認するには、次の文を含む phpinfo.php という名前の PHP ファイルを作成し、サイトのルート フォルダーに保存します。

<?php phpinfo(); ?>

次に、このファイルを参照して upload_max_size の値を確認します。

メディア コンテンツ (uploads フォルダー) のサイズが 10 GB で Web アプリケーションのサイズが 1 GB の場合、どの料金レベルが適切か検討する

各料金レベルでサポートされている Storage の容量は、Shared では 1 GB、Basic では 10 GB、Standard では 50 GB です。WebSites の Storage を最大限に活用したいとお考えの場合は、uploads フォルダーに格納されているすべてのメディア コンテンツを Azure Storage に移動し (この場合 0.048 米ドル/GB の料金がかかります)、WordPress サイトのメディア コンテンツの管理に Azure Storage プラグイン (英語) を使用します。これにより、メディア コンテンツを Web アプリケーションと分離させることができます。

また、メディア コンテンツのサービスを提供する Azure Storage アカウントの Azure CDN エンドポイントを作成することもできます。これを行うには、まずプラグインの設定ページで CNAME プロパティの設定を確認し、以下の欄に Azure CDN の名前 (http://az628210.vo.msecnd.net/ など) を入力します。

WordPress サイトで SSL をセットアップする方法

SSL は、Standard レベルと Basic レベルでのみサポートされています。サイトに SSL のサポートを追加する場合は、下記に関するページを参照してください。

Azure WebSites で mod_rewrite は使用できるか

Azure WebSites では IIS Web サーバーを使用しているため、Apache モジュールである mod_rewrite は使用できません。Azure WebSites ではその代わりに Url Rewrite モジュールが既定で有効になっており、web.config ファイルを使用して書き換えルールやリダイレクト ルールを作成できます。

これを行うには、まずサイトのルート フォルダー (D:homesitewwwroot) にある web.config ファイルを開きます。このフォルダーに web.config が存在しない場合は作成します。

次に、下記の XML 文をコピーして system.webServer 要素に貼り付けます。

<rewrite>
<rules>
<rule name="Main Rule" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="index.php" />
</rule>
</rules>
</rewrite>

このルールは、すべての要求された URL について照合を行います。URL に対応するファイルやフォルダーがファイル システム内に存在しない場合は、ルールに従って URL が index.php に書き換えられます。その次に、書き換えられる前の URL に含まれている REQUEST_URI サーバー変数に基づいて、どのコンテンツをサービスとして提供するかが決定されます。

URL の書き換えルールの作成についての詳細は、「URL の書き換えに関する 10 のヒントとテクニック (英語)」を参照してください。

依存要求を .woff ファイルで行うときに 404.3 “Mime Type missing” エラーが発生する場合の対処

Azure WebSites の既定では .woff 拡張子は無効化されています。WordPress などのアプリケーションで .woff ファイルを使用する場合は、サイトのルート フォルダーにある web.config ファイルに下記の <system.webServer> の部分を追加します。

<configuration>
<system.webServer>
<staticContent>
   <mimeMap fileExtension=".woff" mimeType="application/x-font-woff" />     </staticContent>
</system.webServer>
</configuration>

その後、Web サイトを再起動します。

Azure で実行している WordPress サイトのページの読み込みが遅い場合の対処

WordPress サイトの速度が遅い場合は、次の項目について確認してください。

  • 料金レベルが Free ではありませんか。

Free レベルのパフォーマンスは運用環境には不十分です。Shared、Basic、Standard のいずれかのレベルへのアップグレードをお勧めします。Azure WebSites の料金詳細ページで各料金レベルの機能を確認し、適切なレベルを選択してください。

  • Web サイトとデータベースが存在するデータ センターが異なっていませんか。

Web サイトが米国西部、データベースが米国東部に存在するなど、コンポーネントが存在するデータセンターの場所が異なっていると、データベースを呼び出すときにネットワークのレイテンシの影響によりページの読み込みが遅くなる場合があります。Web サイトとデータベースは同じリージョンの同じデータセンターに配置することをお勧めします。

  • 無料の ClearDB MySQL データベースを使用していませんか。

無料の ClearDB MySQL データベースは、運用環境の Web サイトに向けたものではありません。Azure 用の ClearDB のプラン (英語)Azure ストアから購入する方法をご確認ください。

PHP のエラーの診断結果を取得する方法

Azure WebSites では、Web サーバーの診断を有効にすると Web サーバーのログ記録、詳細なエラー メッセージ、失敗した要求のトレースなどが得られます。エラー情報の取得に関する詳細については、Azure WebSites での PHP の診断に関するブログ (英語) を参照してください。

新たに導入された Diagnostics as a Service (DaaS) では、これらのログを解釈し、問題解決を支援したり、ガイドとして役立つ情報を提供したりします。詳細については、Azure WebSites の Diagnostic as a Service (DaaS) に関するブログを参照してください。

WordPress で詳細なデバッグ機能を有効化する方法

WordPress では、WordPress サイトのデバッグに関してさまざまなオプションを提供しています。WordPress サイトのデバッグ機能を有効にするには、WP_DEBUG 定数をオンにします。既定では、この定数は wp-config.php ファイルでオフに設定されています。

define('WP_DEBUG', false);

この値を TRUE に設定して有効化します。

define('WP_DEBUG', true);

デバッグ作業が終了した後は、この機能は必ずオフにしてください。WordPress のデバッグに関する詳細は、「WordPress でのデバッグ (英語)」を参照してください。

WordPress サイトで電子メール サービスを有効化する方法

Azure WebSites では電子メールおよび SMTP をサポートしていないため、Azure ストアで SendGrid を購入する必要があります。SendGrid の Free プラン (最大で 1 か月に 25,000 通の電子メールを利用可能) で、たいていの WordPress サイトに十分対応可能です。Free プランで不十分な場合は、こちらのページ (英語) で Azure 用の SendGrid のプランをご確認いただけます。

詳細については、「PHP から SendGrid 電子メール サービスを使用する方法」を参照してください。

WordPress サイトのバックアップと復元の方法

Azure WebSites には自動バックアップ機能と自動復元機能があります。詳細については、Azure WebSites のバックアップ方法復元方法を参照してください。

WordPress サイトはオンラインで編集可能か

WebSites では、Visual Studio の機能を備えたオンライン エディターが使用できます。詳細については、Monaco を使用した Azure WebSites のオンライン編集に関するページ (英語) を参照してください。

WordPress でデータベース接続時のエラーを修正する方法

WordPress がデータベースと接続できない場合にはエラーが発生します。その原因には次のようなものが考えられます。

  • wp-config.php ファイルのデータベース情報が不正確

MySQL Client でデータベースにアクセスして wp-config.php の情報を訂正します。

  • WordPress サイトのフロントエンドとバックエンドのそれぞれでエラーの種類が異なるかどうかを確認する

WordPress の管理ページで “One or more database tables are unavailable. The database may need to be repaired” などの異なる種類のエラーが発生している場合には、データベースを修復する必要があります。この場合、wp-config.php に次の文を追加します。

define('WP_ALLOW_REPAIR', true);

追加したら、http://<サイトの URL>/wp-admin/maint/repair.php に移動し確認します。

いったんこの定義を設定すると、ユーザーはこの機能にアクセスする際にログインする必要がなくなります。この機能は破損したデータベースを修復することを主目的としたもので、データベースが破損している場合にはユーザーがログインできないことが多く、そうした状況に対応するためにこのような仕様になっています。データベースの修正と最適化が終了したら、必ずこの部分を wp-config.php から削除してください。

  • wp-config.php が破損している可能性がある

wp-config.php を修正して、最終更新日時のタイム スタンプを変更します。

  • 読み込み負荷が高いときにサイトで断続的にエラーが発生する

wp-includes/wp-db.php ファイルを下記のように変更して WordPress との固定接続を使用します。

PHP のバージョンが 5.4 以前の WordPress の場合

//1147 行目をコメントアウト
//$this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
//次の行を追加

$this->dbh = mysql_pconnect( $this->dbhost, $this->dbuser, $this->dbpassword,  $client_flags );
if ( false !== $error_reporting ) {
error_reporting( $error_reporting );
}
} else {
//1152 行目をコメントアウト
//$this->dbh = mysql_connect( $this->dbhost, $this->dbuser, $this->dbpassword, $new_link, $client_flags );
//次の行を追加
$this->dbh = @mysql_pconnect( $this->dbhost, $this->dbuser, $this->dbpassword,  $client_flags );
}

PHP のバージョンが 5.5 以降の WordPress 3.9.1 の場合

//1378 行目
if ( WP_DEBUG ) {
     //$host の前に 'p:'を追加
     mysqli_real_connect( $this->dbh, 'p:'.$host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
              }
      else {
      //$host の前に 'p:'を追加
     @mysqli_real_connect( $this->dbh, 'p:'.$host, $this->dbuser, $this->dbpassword, null, $port, $socket, $client_flags );
            }

WordPress の自動機能が有効になっている場合、このファイルが上書きされ変更内容が失われる場合があります。このため、WebJob 機能を使用してファイルの変更の有無を確認し、この変更が wp-db.php ファイルに適用されていない場合は改めて適用することをお勧めします。WordPress で使用している PHP のバージョンが 5.4 またはそれ以前の場合は、こちらのリンクから WebJob をダウンロードできます。PHP 5.5 を使用している場合はこちらのリンクをご利用ください。

  • Web サイトのサービスがデータベースに接続できるかどうかを確認する

データベースに接続できるかどうかを確認するには、testdbconnection.php という名前の新しいファイルを作成して、次のコードを貼り付けます。

<?php
//データベースの接続情報に合わせて、mysql_connect の
//ホスト名、ユーザー、パスワードを設定
$link = mysql_connect('localhost', 'username', 'password');
if (!$link) {
die('Could not connect: ' . mysql_error());
}
echo 'Connected successfully';
mysql_close($link);
?>

ブラウザでこのページを実行して “Connected successfully” というメッセージが表示されたら、Web サイトのサービスがデータベースに接続可能であるということです。“Could not connect” というメッセージが表示された場合は、MySQL のエラーを確認して問題の原因を特定します。“Could not connect” が表示される場合に問題を解決できないときは、Azure サポートまでご連絡ください。

“1203 SQLSTATE: 42000 (ER_TOO_MANY_USER_CONNECTIONS)” というエラーの解決方法

解決方法は、使用している MySQL サーバーの種類によって異なります。

  • ClearDB MySQL データベースを使用している場合、データベース プランに応じて max_user_connections の制限が適用されます。詳細についてはこちらのページ (英語) を参照してください。制限が適用された場合はこのエラーが発生します。プランをアップグレードするとこの問題は解消されます。
  • MySQL Azure VM で WordPress サイト用のデータベースをホストしている場合は、my.ini (Windows の場合) または my.cnf (Linux の場合) の構成を編集します。
max_connections = 250

max_connections の設定値が高過ぎると、“Out of memory” エラーが発生して MySQL サーバーが強制終了します。MySQL サーバーの VM のメモリ容量を考慮しつつ適切な値を設定してください。

白い画面や空白ページが表示される場合の対処

Web サイトにアクセスしたときに白い画面や空白ページが表示される場合は、プラグインかテーマに関する問題が考えられます。こちらの手順ごとの説明 (英語) を参考にしながら、問題の原因となっているテーマやプラグインを特定してください。

メモリ容量不足のエラーが発生した場合の対処

メモリ容量は、既定では 128 MB に設定されています。メモリ容量の制限は次のいずれかの方法で引き上げることが可能です。

  • wp-config.php に次の文を追加する
define('WP_MEMORY_LIMIT', '128M');
  • サイトのルート (D:homesitewwwroot) にある .user.ini に次の文を追加する
memory_limit=256M

その後、Web サイトを再起動します。

Azure WebSites の機能やドキュメントへのフィードバックについて

新しいドキュメントへのご意見や不足している情報に関するご要望、新機能や既存機能へのご意見は、フォーラム (英語) からエンジニアリング チームまでお寄せください。

関連情報へのリンク

WordPress のトラブルシューティング ガイド (英語)
WordPress のサポート (英語)

Reusing ViewModels in a Universal App – Part 5

Wow, its been quite the journey but here we are finally at the end.

To restate the previous articles – We took a Windows store app that was coded without a ViewModel.  We refactored the code to have a ViewModel which is placed in a shared location, along with the Model.  The final View has almost no code and is decoupled from the XAML.  The interaction between the ViewModel and View is all facilitated by bindings, keeping the ViewModel logic abstract from the details of the View.

The last thing we are going to do is to develop a new View for Windows Phone and reuse both the Model and ViewModel.

The Phone View

Coding the phone view was really simple.  I “cheated” a little and made the phone view very similar to the desktop view.  It consists of a ListBox, a TextBox and a bunch of buttons.  The MainPage class does the same thing as the Windows version – constructs an instance of the ViewModel and sets the DataContext to point to it.  The XAML code looks very similar – just things are in different positions and the styles are different.

The whole thing took me maybe 10 mins to code up and tweak the layout to get the sizes and spacing right.   Which shows how empowering a reusable ViewModel is.

I wanted to make the phone view at least a little different, so instead of 2 radio buttons to switch between Hex and Decimal I used a button on the command bar. 

Due to that difference we can’t deal with the button the same way the we did in Windows.  So I enhanced the ViewModel to support a SwitchModeCommand which toggles between the 2 modes. 

I wanted to call that out because, in my opinion, it is OK for a ViewModel to have pieces which are targeted at one platform vs the other.  When used infrequently it seems like a very practical way to develop your application.  However it would be concerning if the shared part of your ViewModel starts becoming a smaller and smaller percentage of the total ViewModel code.  If that was the case then I’d start questioning what is going on.  On one extreme it could indicate a bad ViewModel design.  On the other extreme it could indicate that the Views are so different that sharing code isn’t practical.  It would really be case-by-case, although most times it is bad ViewModel design.

Wait There’s More

Just like in your favourite infomercial, don’t order yet – more cool stuff to come.

Because Views are now so easy to code we can add more than 1 for phone.  For example we could easily support a Landscape view in addition to the Portrait one we just created.

To do this we first want to make the markup easy to replace at runtime.  Enter the ContentControl.  This is a control which takes some data (Content) and markup (ContentTemplate).  It then combines the 2 – making the Content the DataContext of the template.  In this case our data is fixed (the ViewModel) but we can switch the template at runtime for different renderings. 

This may sound like magic, but it is actually a key piece of XAML’s composability.  For example Button is a subclass of ContentControl.  That is what allows you to put stuff like text, images, etc inside a button. 

To make the change we take our View markup and wrap it inside a DataTemplate element and then put it in the Resources section with a key name. 

    <Page.Resources>

        <DataTemplate x:Key=”PortraitViewTemplate”>

            <Grid>

                <Grid.RowDefinitions>

                    <RowDefinition Height=”*” />

                    <RowDefinition Height=”Auto” />

                    <RowDefinition Height=”Auto” />

                </Grid.RowDefinitions>

                <Grid.ColumnDefinitions>

                    <ColumnDefinition Width=”*” />

                </Grid.ColumnDefinitions>

               

                <Grid

                    x:Name=”StackGrid”

                    Grid.Row=”0″

                    Grid.Column=”0″

                    >

…snip…

 

We then put the ContentControl in our page and set its properties.

        <ContentControl

            Content=”{Binding}”

            ContentTemplate=”{StaticResource PortraitViewTemplate}”

            />

 

Now we are prepped to add a Landscape View.  To do that I define a new DataTemplate in the resources and call it LandscapeViewTemplate.  Inside that template we define the markup we want for the landscape view.  Then we need to add the code to switch between the 2 templates appropriately.  For that we need to:

·        Update the manifest to indicate we support both portrait and landscape modes

·        Give our ContentControl a name so we can reference it in our View code (appropriate since this is a View layer thing)

·        Set the right template for both the initial state and when orientation changes

And so here is the XAML:

        <ContentControl

            x:Name=”PageContentControl”

            Content=”{Binding}”

            />

 

And here is the page code:

        public MainPage()

        {

            _displayInfo = DisplayInformation.GetForCurrentView();

            _displayInfo.OrientationChanged += OnOrientationChanged;

 

            _viewModel = newStackCalculatorViewModel();

            this.DataContext = _viewModel;

 

            this.InitializeComponent();

 

            this.NavigationCacheMode = NavigationCacheMode.Required;

            UpdateViewTemplate();

        }

 

        void UpdateViewTemplate()

        {

            string resourceName;

 

            if(_displayInfo.CurrentOrientation == DisplayOrientations.Landscape)

            {

                resourceName = LandscapeViewTemplate;

            }

            else

            {

                resourceName = PortraitViewTemplate;

            }

 

            var template = (DataTemplate) this.Resources[resourceName];

 

            this.PageContentControl.ContentTemplate = template;

        }

 

        void OnOrientationChanged(DisplayInformation sender, object args)

        {

            UpdateViewTemplate();

        }

 And here is the end result:

Whats Next

Obviously MyCalc is not a finished and polished app ready to be published to the app store.  So there is a decent amount of work left to get to that point beyond the ViewModel focus of this series.

I’m just going to enumerate a few things that would be at the top of my list to fix, if I were to seriously try and take this to the app store.

Too many commands – right now add, subtract, multiply and divide each have their own command.  When I think about new features like square root and trig functions this would cause an explosion of commands.  Likely this should be handled in a way similar to the command to add to the text box, using the parameter to differentiate the buttons.  I’m not really thrilled with a huge switch statement in the code, but it seems the lesser of 2 evils compared with tens of command properties and backing methods.  Seems like having a command for all the buttons which share the same number or arguments is a decent compromise between the 2 extremes.

ListBox doesn’t scroll – if one adds enough numbers to fill the viewable area of the list box, and then adds another the ListBox doesn’t scroll the new number into view.  This could be solved in multiple ways.  One way is an attached service that you attach to the ListBox control.  It can monitor when the Items collection gets a new item added to the end, and call ListBox.ScrollIntoView with that new item.

AppBarButton – I don’t like how the AppBar takes up so much space for just the one button.  I’d like to get rid of it.  Perhaps some “tabs” in the UI to allow the user to expose additional settings/commands since there isn’t enough room to put everything on a single page.

Enter Button – it would be cool if the user didn’t have to hit Enter all the time.  Wouldn’t it be cool to type in that second number and be able to hit Add immediately, without hitting Enter first.  This functionality could either be pushed into the Model, or we could have the ViewModel push and pop the number appropriately as the user types.  Either approach has its own pros & cons.

Better UI – My dev design UI works, but isn’t anywhere close to pretty or polished.  So having UI designed by someone with skills would be a big plus.

Bring Orientation Support To Desktop – Why can’t the desktop app work in Portrait as well as Landscape?  No good reason.  Seems like there is also an opportunity for more code sharing…

Wrapping it Up

Having reusable ViewModel enabled me to get my Windows app running on phone supporting both Landscape and Portrait views really easily.  I probably spent about 30 mins coding. 

If we were to have estimated the cost to add a phone version of the app based on the code in part 1, the estimate would have been much higher than 30 mins.  To add both Landscape and Portrait views would have caused the cost to climb even more.  As well as the end result would have left us with a lot more code, raising future costs for maintenance and additional features.

It is easy to image going beyond the simple landscape & portrait views and develop skins – user switchable views to make it look like a physical calculator, or like all the buttons are made of wood, etc…

I hope this series of articles have shown you the power of having a reusable view model, and also a bit of education on how to design and develop a ViewModel.

As always complete code is attached.

Reusing ViewModels in a Universal App – Part 4

To restate where part 3 ended – We have migrated all the buttons and TextBox to use the ViewModel.  What is left is the display of the items on the stack and the mode radio buttons.

Handling Radio Buttons

There are a few different ViewModel patterns which work with RadioButtons.

Option #1 – Since RadioButton supports Command we could make a ChangeModeCommand which takes a parameter of the new mode. 

The pros of this solution are:

·        It works well if other supported views uses controls which support commands for changing modes (i.e. some kind of button style)

The cons are:

·        Can’t set initial button state

·        Doesn’t update state of other buttons 

·        CanExecute should always return true, otherwise radio buttons will get disabled

Those issues can be solved, but will require more work.  Which implies we should only go this route if we need commands for the other view implementations.  At this point we haven’t designed the phone UI, so going with a low cost solution is probably best.  Plus I’d like to demonstrate some other techniques.

The next 2 options are variations on 2 way bindings.

Options #2 – Add an IsHexMode and IsDecimalMode bool properties to the ViewModel and 2 way bind the RadioButton.IsChecked to them. 

The pros of this solution are:

·        Very simple and easy to understand

·        Allows configuring initial control state

·        Updates control state of all RadioButtons

The cons are:

·        Only works well for RadioButton UI

·        Doesn’t scale if the number of modes increases

Option #3 – 2 way bind to the Mode property and use a converter to convert back and forth between CalculatorMode and bool.

The pros of this solution are:

·        Just 1 property regardless of number of modes

·        Allows configuring initial control state

·        Updates control state of all RadioButtons

·        Different (or none) converters can be used for other UIs (i.e. enums work well with ComboBoxes)

The cons are:

·        Have to be careful that we have 1 “winner” when buttons change (i.e. 1 RadioButton should change the mode, the others shouldn’t even though their IsChecked property changes)

 

In this example we are going with Option #3 because not only is it a good choice, but it allows me to demonstrate a new ViewModel technique.  To implement a converter we define a class and have it implement IValueConverter.  Since we will be using it in 2 way bindings we implement both Convert and ConvertBack.

If this was WPF we’d be able to pass the enum value in as the ConverterParameter, but Windows store apps don’t support x:Static like WPF does, so we need to pass the value in as a string.  Then inside the converter parse the string into the right mode enum value.

Here is the implementation:

    publicclassBoolToCalculatorModeConverter : IValueConverter

    {

        public BoolToCalculatorModeConverter()

        {

            // nothing

        }

 

        publicobject Convert(object value, Type targetType, object parameter, string language)

        {

            var desiredMode = StringToMode((string)parameter);

 

            var acutalMode = (CalculatorViewMode)value;

 

            return (desiredMode == acutalMode);

        }

 

        publicobject ConvertBack(object value, Type targetType, object parameter, string language)

        {

            var state = (bool)value;

            var desiredMode = StringToMode((string)parameter);

 

            if(state)

            {

                return desiredMode;

            }

            else

            {

                // since we don’t know the right value, just return null

                returnnull;

            }

        }

 

        CalculatorViewMode StringToMode(string value)

        {

            switch(value)

            {

                case“Decimal”:

                    returnCalculatorViewMode.Decimal;

                case“Hex”:

                    returnCalculatorViewMode.Hex;

                default:

                    thrownewNotSupportedException();

            }

        }

    }

 

You’ll notice in ConvertBack we solve the issue of the unchecked RadioButtons from changing the mode by returning null, which isn’t a valid enum value.  That causes the binding to fail and not update the property.

Then in the XAML we first declare an instance of the converter in the Resources section, and then update the RadioButton to bind to the value using the Converter.  Here is the code for one of the RadioButtons:

            <RadioButton

                x:Name=”_HexSelection”

                Grid.Column=”0″

                Grid.Row=”1″

                Style=”{StaticResource RadioButtonStyle}”

                Content=”Hex”

                GroupName=”NumbericType

                IsChecked=”{Binding Mode, Converter={StaticResource BoolToCalculatorModeConverter}, ConverterParameter=Hex, Mode=TwoWay}”

                />

 

And of course we need to go into our View and rip out all the code which interacted with the RadioButtons.

Picking a Solution for Stack Content Display

Now we are down to the last bit of View code – that dealing with populating the ListBox with the stack contents, formatting appropriately for the mode.

If this was WPF we could use a MultiBinding and IMultiValueConverter.  That would allow us to bind to the number and mode, and in the converter format the value appropriately and return it.  It would be re-evaluated when the values of the bindings change.  However this isn’t available for Windows Store apps currently.

We could also solve this with a custom control for the content for the ListBoxItems.  But that seems like a heavy handed solution.  It also limits reusability as other Views may not be able to re-use that control for whatever reason.

Another way is to expose a collection of strings from the ViewModel and then update this collection when the mode changes and when the stack changes.  This can be a reasonable solution and is pretty straightforward to implement.  Something like a ConvertingReadOnlyObservableCollection can help make that happen.  When the mode changes you could either re-build the shadow collection with newly formatted strings.  Or the collection could be a ViewModel class with a string property for the formatted string.  Then when the mode changes one can enumerate the collection and tell each object to re-format, which as it does will raise a PropertyChanged event to cause the bindings to update.

I’m going to go with a different solution, which uses an Attached Service (some people call it an Attached Behavior).  If you haven’t had experiences with these then it may feel weird and require some getting used to.  It will allow the ItemsControl and bindings do the work, rather than us having to explicitly code it.

Attached Services

You may be aware that XAML controls use a thing called DependencyProperty.  This allows controls to do stuff like inherit property values from their parent controls in a seamless way for us using the controls.  A closely related thing is an AttachedDependencyProperty.  This is a property defined on one class, but you actually set/retrieve the values on instances of other classes – weird, right?

I’ll not go into how this is implemented internally, just believe that it does work and allows us to do some things which are usually unconventional.

I bet you’ve used these before and never realized you were using attached properties.  For example if you add Grid.Column=”3” onto a TextBox then you are setting the value for an attached property.  The Grid implementation then reads these values when performing layout.

One of the tricky things you can do with an attached property is register a callback for when the property is changed.  This callback gets as the sender the object that the property has been applied to.  At that point you can interact with that object – get/set properties, call methods, etc…  It is typically the implementation of the changed callback that turns this into a “service” instead of just a stored value.

What is great about attached services is that if written right they can apply to just about any control, even custom ones.  And you can apply different attached services to the same control instance, allowing you to combine behaviors.  This is very superior to traditional methods like sub-classing or custom controls.

CalculatorNumberFormatter

The attached service we are going to implement is CalculatorNumberFormatter.  It will define 3 attached properties.  2 are input properties – Number and Mode.  Number is designed to be bound an integer value.  Mode is designed to be bound to the current Mode.  When either of those properties change it will run code which will correctly format the integer into a string based on the mode.  The resulting value will be placed in an output parameter called Text.

Then the control that these properties are attached to can bind it’s Content/Text property to CalculatorNumberFormatter.Text. 

Not only will this correctly format the number correctly initially, but it will respond if the mode changes.  And this will happen in a better way than the initial View oriented implementation we had, because it will not clear and rebuild the listbox.  It also works if the ListBox (or any ItemsControl) is virtualizing (but we will not dive into that in this series).

Before we look at the code I’d like to point out that we could have avoided the Text property and instead casted the DependencyObject we are attached to into what control it actually is, like TextBlock.  However this limits reuse as it wouldn’t work with other controls.

Here is the code for one of the attached properties.  You’ll notice we both define the static property, and add Get/Set methods.  Those methods are helpful, but also required for the XAML to compile.

        publicstaticreadonlyDependencyProperty ModeProperty = DependencyProperty.RegisterAttached(

                                                                        “Mode”,

                                                                        typeof(CalculatorViewMode),

                                                                        typeof(CalculatorNumberFormatter),

                                                                        newPropertyMetadata(null, ModeProperty_PropertyChanged));

 

 

        publicstaticCalculatorViewMode GetMode(DependencyObject obj) { return (CalculatorViewMode)obj.GetValue(ModeProperty); }

        publicstaticvoid SetMode(DependencyObject obj, CalculatorViewMode value) { obj.SetValue(ModeProperty, value); }

 

        staticprivatevoid ModeProperty_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)

        {

            FormatNumber(o);

        }

 

The Number and Text properties are similar – just different names and types.

FormatNumber gets the Number and Mode values (handling if they aren’t set) and sets the Text property.

        staticvoid FormatNumber(DependencyObject o)

        {

            var mode = (CalculatorViewMode?) o.GetValue(ModeProperty);

            var value = (Int64?)o.GetValue(NumberProperty);

 

            if (mode.HasValue && value.HasValue)

            {

                string text;

 

                if (mode == CalculatorViewMode.Hex)

                {

                    text = String.Format(CultureInfo.CurrentCulture, “0x{0:X}”, value.Value);

                }

                else

                {

                    text = String.Format(CultureInfo.CurrentCulture, “{0:G}”, value.Value);

                }

 

                SetText(o, text);

            }

        }

 

Applying CalculatorNumberFormatter to the ListBox

In order to apply this attached service to the ListBox we start off by binding the ItemsSource property to the Stack collection.  Logic inside the control will create a child control for each item.  We also set the ItemTemplate property so we can control the details of what those child controls expose.

One thing to be aware of is that the DataContext for the ListBoxItem children is not the ViewModel, but a specific item from the ItemsSource collection – in this case an int from our Stack collection.  So binding without a Path value will give use that object.  To get a reference to our view model, which has the Mode property we need, we need to use some additional features of binding.  Our choices in a Windows Store app are more limited than in WPF, but we only need 1 way that works.  In this case using ElementName and specifying an element outside the ListBox will work nicely.

That handles binding the Number and Mode properties.  All that is left is to connect TextBlock.Text to CalculatorNumberFormatter.Text.  I tried doing this the typical way and was having issues getting it to work.  So I wound up reversing it and making the binding 2 way to feed the value to the right place.

The result is this:

            <ListBox

                x:Name=”_StackBox”

                Grid.Column=”0″

                Grid.ColumnSpan=”2″

                Grid.Row=”0″

                Margin=”4″

                FontSize=”32″

                ItemContainerStyle=”{StaticResource ListBoxItemStyle}”

                ItemsSource=”{Binding Calculator.Stack}”

                >

                <ListBox.ItemTemplate>

                    <DataTemplate>

                        <TextBlock

                            local:CalculatorNumberFormatter.Number=”{Binding}”

                            local:CalculatorNumberFormatter.Mode=”{Binding DataContext.Mode, ElementName=StackGrid}”

                            local:CalculatorNumberFormatter.Text=”{Binding Text, RelativeSource={RelativeSource Mode=Self}, Mode=TwoWay}”

                            />

                    </DataTemplate>

                </ListBox.ItemTemplate>

            </ListBox>

 

We can then clean out the ListBox related code out of the view.

Wrapping it Up

We are now done with the first phase.  Our MainPage class no longer has any logic in it.  The only thing we have in there that isn’t part of the VS broiler plate is the code to create the ViewModel and assign the DataContext.

We learned a few new techniques to decoupling logic so we can have a View independent ViewModel and maximize code reusability.

·        ValueConverters can be used to bridge the gap between how our ViewModel works and the needs of a specific control

·        Attached services are a powerful technique to connect custom logic to any control, helping us customize behaviors and overcome system limitations

In the next edition we’ll take this completed ViewModel and build a phone view on top of it – proving that we can re-use it for different Views.

 

QuickHit Video – Getting Started with Visual Studio Online

I just posted a new video in the series (is it a series yet if there are only two?): QuickHit Video -  Getting Started with Visual Studio Online

It’s actually a re-post of a FlashCast video I did earlier in the summer, with a few annotations to catch you up on updates as well.

Getting Started with Visual Studio Online

Hope you enjoy it!  As always, please let me know if there are any topics you’d like to learn more about!

APC 2014 – registration closes today!

Registration for APC 2014 closes today (Friday 29th August) at 5pm AEST! 

With an incredible line up of speakers, a packed agenda and a special offer on a Surface Pro 3 it’s an event not to be missed.

Still undecided?  Don’t take our word for it, hear from our Partners why they attend APC each year.

Make sure you secure your spot today.

See you on the Gold Coast.