Xamarin.FormsでDynamicResourceを使ったテーマカラーの切り替えでハマった

Xamarin.Formsで動的なテーマカラーの切り替えを実装していて少しハマった件について書いておきます。

【やりたいこと】

App.xaml内に定義したColorリソースの中身を入れ替えてDynamicResourceで参照している箇所を変えたい

<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="sample.App">
  <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="Primary">#000000</Color>
            <Color x:Key="PrimaryDark">#1976D2</Color>
            <Color x:Key="Accent">#00ff00</Color>
            <Color x:Key="LightBackgroundColor">#FAFAFA</Color>
            <Color x:Key="DarkBackgroundColor">#C0C0C0</Color>
            <Color x:Key="MediumGrayTextColor">#4d4d4d</Color>
            <Color x:Key="LightTextColor">#999999</Color>

            <Style TargetType="NavigationPage">
                <Setter Property="BarBackgroundColor" Value="{StaticResource Primary}" />
                <Setter Property="BarTextColor" Value="White" />
            </Style>
        </ResourceDictionary>
    </Application.Resources>
</Application>

【やったこと】

以下のブログにズバリ書いてあるので、参考にしながら実装しました。
blog.xamarin.com

App.Current.Resources ["backgroundColor"] = Color.White;
App.Current.Resources ["textColor"] = Color.Black;

が、なんどやってもDynamicにリソースが変わってくれません。。。

【調査結果】

いろいろ調べた結果、原因はColorクラスでした。

なんと!
Xamarin.Formsで使えるColorクラスというのはどうやらいくつかあるようなのです!!
(知っている人には当たり前かもしれませんが ^^;)


・System.Drawing.Color ← これを使っていた(不正解)
・Xamarin.Forms.Color ← 正解はこれ
Android.Graphics.Color
・(もしかしたら他にもあるかも?)

Xamarin.Forms.Colorを使えば、Dynamicにリソース変更を反映させることが出来ます。

XAMLのIntelliSenseが効かない&&クイックアクションに「using Xamarin.Forms;」が出てこない
という状況だったのでハマってしまいました。

Xamarin Mac Agentを使ってMacに接続できない(する気配すらない)時の確認ポイント

ちまちまXamarinやってます。

iOS版のビルドなどを実行するにはMacと接続する必要があります。
そのために、「Xamarin Mac Agent」なるものを使うのですが、ハマったのでメモしておきます。

つながらない場合は以下の点を確認してみてください。
つながるようになるかもしれません。

1.Macのリモートログインが有効になっているか

「システム環境設定」→「共有」→「リモートログイン」のチェックボックスを入れてください。
ログインユーザーのアクセスが許可されているか確認して、許可されていない場合は「+」で追加します。

2. XCode(AppleID)の設定が完了しているか

基本的には↓の通りですが、一部異なる箇所がありました。
itblogdsi.blog.fc2.com

Accountボタンを押し、AppleIDを「+」で追加します。
追加したら、AppleIDが表示されますので、View Detailsボタンをクリックします。

私の環境では「View Details」ボタンはありませんでした。
代わりに「Manage Certificates...」ボタンを押します。

iOS Development のCreateボタンを押して、Doneボタンを押します。

私の環境では「iOS Development のCreate」ボタンはありませんでした。
代わりに左下の「+」を押して出てくる「iOS Development」をクリックした後Doneします。

3.ネットワークに繋がっているか

ここでだいぶはまって心が折れかけました。
Xamarin Mac Agentの「接続」ボタンを押せども押せども接続する気配すら見せてくれません。
VirtualBox上のWindowsからMacに接続しようとしていたのですが、なんとネットワークが切断されていました。
直前までは繋がっていたのでなかなか気づけなかった。。。
VMを再起動して問題は解決しました。


以上、誰かの助けになれば幸いです。
誤りなどありましたらご指摘ください。

VisualStudio2017のネイティブメモリ診断機能が使えなくなった時の対処法

VisualStudio 2017便利ですね。

なんと、ネイティブメモリの解析が出来てしまいます。
スナップショット取って比較したり出来るので、メモリリークも簡単に見つかります。

以下の記事は2015ですが、概要はだいたい同じだと思います。
qiita.com

さて、本題ですが、私の環境でネイティブメモリ診断機能を使用していたときに遭遇したエラーと対処方法を忘備録として残しておきます。

【現象】
デフォルトではネイティブメモリの診断機能は無効になっているため、
デバッガーでアプリケーションを起動して有効にした後にデバッガーを再起動する必要があります。
再起動後、診断ツールの「メモリ使用量」にこんなメッセージが出ていました。

既に処理中のヒープセッションが存在するため、ネイティブメモリのプロファイルセッションを開始できません。Windowsは、コンピューターごとに1つのアクティブヒープセッションしかサポートしません。ほかのVisual Studioインスタンスまたはほかのパフォーマンス分析ツールを閉じてください。

なんのこっちゃ。

【対処法】
タスクマネージャーを開いて下のやつをkillってください。
C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\DiagnosticsHub.Collection.Service\StandardCollector.Service.exe

その後、再びデバッガーを起動すれば診断ツールが復活していることでしょう。
(少なくとも私の環境では復活しました)

誰かのお役に立てば幸いです。

それではまた。

std::tr2::sys::pathクラスの内容出力系関数の比較

今回はC++の話です。

たまに使おうとするといつも使い方を忘れているstd::tr2::sys::pathクラスについて、
文字列出力関係の関数と出力結果をまとめておきます。


パスの連結や比較なども機能として用意してあるようです。以下にまとめてあります。
が、この記事だと出力系がわかりにくかったので。。。
path クラス (C++ 標準テンプレート ライブラリ)


以下のパスを入力として与えてそれぞれの関数で出力した結果は以下の通りです。
(Windowsを想定しているので「\\」で区切っています)

C:\\TestDir1\\TestDir2\\TestFileName.bmp
関数 出力 区切り文字 説明(違ってたら指摘お願いしますm(_ _)m)
basename() TestFileName - ファイル名(拡張子無し)
branch_path() C:/TestDir1/TestDir2 / ファイルのあるディレクトリまでのパス
directory_string() C:\TestDir1\TestDir2\TestFileName.bmp \ フルパス
extension() .bmp - 拡張子部分
external_directory_string() C:\TestDir1\TestDir2\TestFileName.bmp \ フルパス
external_file_string() C:\TestDir1\TestDir2\TestFileName.bmp \ フルパス
filename() TestFileName.bmp - ファイル名(拡張子有り)
file_string() C:\TestDir1\TestDir2\TestFileName.bmp \ フルパス
leaf() TestFileName.bmp - ファイル名(拡張子有り)
parent_path().string() C:/TestDir1/TestDir2 / ファイルのあるディレクトリまでのパス
relative_path() TestDir1/TestDir2/TestFileName.bmp / ドライブ文字以外?(相対?)
remove_filename() C:/TestDir1/TestDir2 / ファイル名以外
remove_leaf() C:/TestDir1 / leaf()以外?(そうなってないけど。。。)
root_directory() / / ルートディレクトリ名
root_name() C: - ルート名
root_path() C:/ / ルートディレクトリパス
stem() TestDir1 -
string() C:/TestDir1 /


なんだかよくわからない結果ですね。。。
同じ出力結果もちらほらとでています。
Linuxなどで出力した結果を比較するともっとわかりやすくなるのかもしれません。
時間があるときに試してみたいと思います。

わかりやすいリファレンスの場所をご存知の方がいらっしゃれば是非教えてください!

VisualStudio2017で拡張機能をインストールしたら落ちる時の対処法

どーも。panjaです。

さっそくVS2017インストールしてみました。
いろいろ環境を作っていたのですが、ある拡張機能をインストールして再起動するとソリューションを開く際に落ちるようになってしまったので、対処法を残しておきます。
同じような現象で困っている人の助けになれば幸いです。

原因の拡張機能は以下のものです。
Productivity Power Tools 2017
blogs.msdn.microsoft.com

上の記事にも書いてありますが、「拡張機能と更新プログラム」から「Productivity Power Tools 2017」をインストールすると次回起動時に以下の拡張機能群が自動でインストールされるように変わったようです。(VS2015までの同様の拡張機能は一つの拡張機能に機能がてんこ盛りというものでした。)
その中のいくつかの機能を有効にするとソリューションが開けなくなりました。

インストールされる機能一覧は以下の通りです。
表中の「落ちる原因?」列が「◯」になっているものを全て無効化するとソリューションを開けるようになりました。

名前 概要(違っていたら教えてくださいm(__)m) 落ちる原因?
Align Assignments Ctrl + Alt + ]で「=」の位置を揃えてくれます ×
Copy as HTML 選択したテキストをHTML形式でクリップボードにコピーしてくれるらしいです ×
Ctrl+Click Go To Definition Ctrl+クリックで定義に移動します ×
Custom Document Well Visual Studio のドキュメント タブの動作を設定できるようにします*1 ×
Double-Click Maximize 検索ウィンドウなどをダブルクリックすると最大化できるようになります
Editor Guidelines 縦線を表示してインデントをわかりやすくしてくれます
Fix Mixed Tabs タブとスペースが混在している場合に教えてくれるようです
Match Margin キャレットの位置と同じテキストを強調表示してスクロールバーにもわかりやすく表示してくれます ×
Middle Click Scroll マウスの真ん中のボタンクリックでスクロールできるようになります
Peek Help F1を押すと表示されるヘルプをインラインで表示させるためのショートカットキーを設定できるようです
Power Commands for Visual Studio その他の(?)便利機能の詰め合わせのようです ×
Quick Launch Tasks クイック起動ツールのアクセス性を向上させ、タスクを設定する機能を追加します*2 ×
Shrink Empty Lines 意味のある行をより多く表示できるようにテキストや数字を含まない行を縮小します
Solution Error Visualizer ソリューションエクスプローラーでエラーや警告を強調表示してくれるようです
Time Stamp Margin デバッグ出力ウィンドウにタイム スタンプを表示する余白を追加します

また、今回開けなかったソリューションの概要は以下の通りです。
この辺りがかなり関係していそうな気がします。
・もともとはVS2013で作成したソリューション
・(Productivity Power Tools 2017を入れる前に)VS2017で開いた際にアップグレードはしていない
C#C++/CLIC++のプロジェクトを含む
・使用しているサードパーティ製ライブラリ:Boost、XercesC++、GoogleTestなど


「Editor Guidelines」を無効化しなければならないので、インデントがわかりづらくなったのがかなりイタいです。
「Indent Guides」という別の拡張機能もあるようですが、残念ながらVS2017には未だ対応していないようです。同じことが実現できる拡張機能をご存知の方、ぜひぜひ教えてください(`・ω・´)ゞ

*1:よくわかっていません

*2:よくわかっていません

Modern UI for WPFのデフォルトAccentColor変更方法と追加方法

どーも。panjaです。

最近、WPFを触っています。
Modern UI for WPF(MUI)を使ってみています。
今回はMUIの小ネタです。

MUIではメインウィンドウのテーマとアクセントカラー(ニッコリマークの背景色)がデフォルトで変更可能になっています。
f:id:panda531531:20170125231757p:plain
上の画像では、テーマがLight、アクセントカラーはcyan(R:0x1b,G:0xa1,B:0xe2)になっています。
初期状態ではテーマは「Light、Dark」、アクセントカラーは「lime、green、emerald、teal、cyancobalt、indigo、violet、pink、magenta、crimson、red、orange、amber、yellow、brown、olive、steel、mauve、taupe」から選択可能です。


今回はこのアクセントカラーの初期値の変更方法と色の追加方法を紹介します。

デフォルトAccentColorの変更方法

  1. GitHubからダウンロードしてきたMUI本体?のソリューション(FirstFloor.ModernUI.sln)を開く
  2. 「Shared\Assets\ModernUI.xaml」を開く
  3. 33、34行目の内容の「#」以下を好きな値に変更する
<!-- default accent colors and brushes -->
<Color x:Key="AccentColor">#1ba1e2</Color>

※16進で「#rrggbb」という並びになっているようです。
4. ソリューションをビルドする
5. お好きなプロジェクトにビルドして出来たバイナリへの参照を追加する

今回はデフォルトのAccentColorをemerald(#008a00)に変更してみました。
変更後してアプリ起動直後に以下のようになっていれば成功です。
f:id:panda531531:20170127004428p:plain
戻るボタンの枠やメインウィンドウの枠も一緒にemeraldになっていますね。

AccentColorの追加方法

  1. MUIのテンプレートを使ってプロジェクトを作成する
  2. 「Pages/Settings/AppearanceViewModel.cs」を開く
  3. 以下に好きな値を追加する
// 20 accent colors from Windows Phone 8
private Color[] accentColors = new Color[]{
    Color.FromRgb(0xa4, 0xc4, 0x00),   // lime
    Color.FromRgb(0x60, 0xa9, 0x17),   // green
    Color.FromRgb(0x00, 0x8a, 0x00),   // emerald
    Color.FromRgb(0x00, 0xab, 0xa9),   // teal
    Color.FromRgb(0x1b, 0xa1, 0xe2),   // cyan
    Color.FromRgb(0x00, 0x50, 0xef),   // cobalt
    Color.FromRgb(0x6a, 0x00, 0xff),   // indigo
    Color.FromRgb(0xaa, 0x00, 0xff),   // violet
    Color.FromRgb(0xf4, 0x72, 0xd0),   // pink
    Color.FromRgb(0xd8, 0x00, 0x73),   // magenta
    Color.FromRgb(0xa2, 0x00, 0x25),   // crimson
    Color.FromRgb(0xe5, 0x14, 0x00),   // red
    Color.FromRgb(0xfa, 0x68, 0x00),   // orange
    Color.FromRgb(0xf0, 0xa3, 0x0a),   // amber
    Color.FromRgb(0xe3, 0xc8, 0x00),   // yellow
    Color.FromRgb(0x82, 0x5a, 0x2c),   // brown
    Color.FromRgb(0x6d, 0x87, 0x64),   // olive
    Color.FromRgb(0x64, 0x76, 0x87),   // steel
    Color.FromRgb(0x76, 0x60, 0x8a),   // mauve
    Color.FromRgb(0x87, 0x79, 0x4e),   // taupe
};

今回はmaroon(#800000)を追加してみました。

Color.FromRgb(0x80, 0x00, 0x00),   // maroon

アプリを起動して「SETTINGS」ページを見てみると色が追加されていることがわかります。
f:id:panda531531:20170127004438p:plain


C++などと違ってフレームワークに乗っかれば簡単に追加できるのでいいですね!

Modern UI for WPFのデフォルトレイアウトを変更する方法

どーも。panjaです。

最近WPFを触っています。
WPFはWinFormsに変わるユーザーインターフェースシステムでなんかかっこいいことが出来そうな感じのものです。
Windows Presentation Foundation - Wikipedia

UIのライブラリ(違う?フレームワーク?)としてModern UI for WPF(MUI)を使用しています。
github.com

あるアプリの作成にMUIを使用していたのですが、どーにもデフォルトのレイアウトが気に入らない!と思ったので変更する方法を調べてみました。
今回はその結果を紹介してみます。

手順は以下の通りです。

  1. Modern UI for WPF(MUI)をダウンロードしてきます。GitHub - firstfloorsoftware/mui: Modern UI for WPF
  2. ダウンロードしたものの中に「FirstFloor.ModernUI.sln」が入っているので開きます。
  3. 「$(SolutionDir)¥FirstFloor.ModernUI¥Themes¥ModernWindow.xaml」を開きます。
  4. 29行目(2017/01/25現在)の
<ControlTemplate TargetType="controls:ModernWindow">

から197行目の

</ControlTemplate>

の中でMUIのテンプレートプロジェクトのメインウィンドウであるModernWindowのレイアウトを決定しているので、変更したい項目を探し出して好きなように変更する。
5. ソリューションをビルドする

これでOKです。
あとは、新しいテンプレートを使用したいプロジェクトの参照に先ほどビルドしたFirstFloor.ModernUI.dll追加すれば使用できるようになります。



以下に、私が実際に行った変更を載せておきます。
具体的には下の画像の赤枠のスペースを無くす変更を行いました。
(青色のRectangleを目一杯広げたページを表示しています。赤枠はGimpで追加しました。)
f:id:panda531531:20170125232135p:plain


ここに表示されるページに関する変更は「ModernWindow.xaml」の160、161行目

<!-- content frame -->
<controls:ModernFrame x:Name="ContentFrame" Grid.Row="3" Grid.RowSpan="2" Margin="42,8,16,16" Source="{Binding ContentSource, RelativeSource={RelativeSource TemplatedParent}, Mode=TwoWay}" ContentLoader="{TemplateBinding ContentLoader}"/>

で行います。
赤枠のスペースを無くすためには、ここに設定してある「Margin="42,8,16,16"」を好きな値に変更してあげれば変更完了です。
今回は「Margin="5,0,5,5"」に変更しました。
結果は以下のようになりました。
f:id:panda531531:20170125231757p:plain

はい。変更できました。



まだまだわからないことだらけのWPF
今後も忘備録的にまとめていきたいと思います。
内容に誤りなどありましたら是非コメントよろしくお願いします。