Xamarin.Formsでぺこぺこ凹むアイコンボタンを作った
Image だけをボタンにしたいケースが多々あり、TapGestureRecognizer で簡単に作れるのですが、押した感がなくイマイチだし好みに合うヤツが見当たらなかったので作りました。
わかりにくいですが、黒い背景でも微妙にボタン裏の色が変わっています。
凹む処理はここを参考にしました。
app-evolve/FavoriteImage.cs at master · xamarinhq/app-evolve · GitHub
最初は Image コントロールだけを拡張していましたが、それだと凹ますと背景色まで凹んでしまいかっこ悪かったので Content View の中に Image を入れました。
IconButton.xaml
<?xml version="1.0" encoding="utf-8" ?> <ContentView x:Class="IconButtonSample.Controls.IconButton" xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"> <Image x:Name="imgIcon" BindingContextChanged="imgIcon_BindingContextChanged" /> </ContentView>
IconButton.xaml.cs
using System; using System.Threading.Tasks; using Xamarin.Forms; namespace IconButtonSample.Controls { public partial class IconButton : ContentView { private bool addedAnimation; public static readonly BindableProperty IconSourceProperty = BindableProperty.Create( "IconSource", typeof(ImageSource), typeof(IconButton), null, propertyChanged: (bindable, oldValue, newValue) => { ((IconButton)bindable).IconSource = (ImageSource)newValue; } ); public ImageSource IconSource { get { return (ImageSource)GetValue(IconSourceProperty); } set { SetValue(IconSourceProperty, value); imgIcon.Source = value; } } public static readonly BindableProperty IconMarginProperty = BindableProperty.Create( "IconMargin", typeof(Thickness), typeof(IconButton), new Thickness(0), propertyChanged: (bindable, oldValue, newValue) => { ((IconButton)bindable).IconMargin = (Thickness)newValue; } ); public Thickness IconMargin { get { return (Thickness)GetValue(IconMarginProperty); } set { SetValue(IconMarginProperty, value); imgIcon.Margin = value; } } public IconButton() { InitializeComponent(); } private void imgIcon_BindingContextChanged(object sender, EventArgs e) { if (addedAnimation || GestureRecognizers.Count == 0) return; var tapGesture = GestureRecognizers[0] as TapGestureRecognizer; if (tapGesture == null) return; tapGesture.Tapped += (tapsender, tape) => { Device.BeginInvokeOnMainThread(async () => await tappedAnimation()); }; addedAnimation = true; } private async Task tappedAnimation() { BackgroundColor = Color.FromRgba(68, 68, 68, 70); await imgIcon.ScaleTo(0.8, 75); await imgIcon.ScaleTo(1.0, 75); BackgroundColor = Color.Transparent; } } }
凹ます処理の前後に Content View 自体の背景色を適当な灰色にしています。
ポイントとして Alpha 値を設定して透過にすることで画面の背景色になじむようにしています。
本来はこの辺も BindableProperty にして公開した方がよかったかもしれませんが、まぁいいかなと。
使う画面.xaml
<control:IconButton HeightRequest="50" HorizontalOptions="Center" IconMargin="10" IconSource="{Binding Source=IconButtonSample.Images.Trash.png, Converter={StaticResource ImageSourceConverter}}" VerticalOptions="Center"> <control:IconButton.GestureRecognizers> <TapGestureRecognizer Command="{Binding Path=DeleteCommand}" /> </control:IconButton.GestureRecognizers> </control:IconButton>
ImageSource を Converter 使っていますが、これは画像を埋め込みリソースにして PCL 側に置いているからです。
その辺も含めてこちらにまるごとサンプルを置いてありますので、ご自由にどうぞー。
Prism 使ってます。
github.com
あとは指が抑えている状態(Hold 時)にも色変えたいけど、とりあえず標準のヤツよりいいから満足です。
更新しました
Xamarin.Forms と Mobile Engagement でユーザー分析しちゃえ!
Xamarin Advent Calendar 2016 - Qiita "その1" 9日目の投稿です。
はい、ということでこんな状況の中、なんとか書きました。。
おはようございます。家庭内パンデミックにより本日が今週初出社です。そして明日がAdventCalendarの担当日です。ヤバいです。そして今日は子供の1歳の誕生日です。#帰りたい #けど帰れない
— SHUNSUKE_KAWAI (@_shunsuke_kawai) 2016年12月8日
ホントは0時きっかりにアップしたかったけど、ご了承ください。
さて、Microsoft さんのイベントで使用したアプリケーションの開発をやった話の記事で簡単に説明しましたが、Azure の Mobile Engagement というサービスはとても楽しいサービスです。
shunsukekawai.hatenablog.com
本記事では Xamarin.Forms でどのように Mobile Engagement でどんなことができるのか、どう使用するかを解説をします。
Mobile Engagement でできること
リアルタイムのアクティブユーザー
こんな感じで今正にアクティブなユーザー数が表示されます。
どの画面がどれだけ使われているか
画面の起動時にコードを1行埋め込むことで、勝手にデータを蓄積してくれます。
どんな画面遷移を行っているか
どこからどこの画面に行ってるかよくわからん図で表示されます。
セッション時間はどのくらいか
どのくらいアクティブにアプリを使ってくれているのかが表示されます。
OSはなにか
サポート対象OSを決める時に役に立ちそう。
どのアプリバージョンを使っているか
ちゃんとユーザーがバージョンアップしてくれてるかわかりますね。
画面サイズはなにか
どのサイズで動かされているかわかると色々対策できそうです。
アプリがクラッシュしている原因とその詳細
StackTrace 的なのも出てます。
と、まぁここに挙げたのは一部ですが、見てるだけでも酒の肴になりそうですね。
Xamarin.Forms に組み込む方法
ここからは Mobile Engagement をどうやってXamarin.Forms に組み込むかです。
Azure ポータルから Mobile Engagement のサービスを追加
- その他設定はよしなに
- 作成完了(3つのアプリが作成されます)
Mobile Engagement アプリはプラットフォームごとに作成する必要があります。
Xamarin.Forms プロジェクトに Mobile Engagement 接続(Android 編)
基本的に以下のチュートリアルに沿って進めていけば大丈夫です。(人任せ)
もう Mobile Engagement 作成は済んでいるので、キーをコピーするところ以降ぐらいから。
Xamarin.Android 用 Azure Mobile Engagement の使用
- 【注意1】NuGet から Microsoft.Azure.Engagement.Xamarin をインストールしたら勝手に作られるフォルダの対処
NuGet からインストールすると勝手にフォルダが作られてそこに Mobile Engagement 用のリソースが置かれます。
(おそらく Xamarin.Android 用だからかな)
そのためその状態でビルドすると以下の様なエラーが発生します。
↓犯人
↓該当するフォルダに移動します。(+になってるヤツを移動した)
- 【注意2】using は Microsoft.Azure.Engagement.Xamarin だけでいい
MainActivity.cs の using は一つだけで大丈夫です。
- 【注意3】MainActivity.cs に EngagementActivity の継承をすることは Xamarin.Forms ではできない(FormsAppCompatActivity をすでに継承しているため)
こっち側の手順でやる必要がある
Azure Mobile Engagement Android SDK の詳細なレポート オプション
Xamarin.Forms プロジェクトに Mobile Engagement 接続(iOS 編)
基本的に以下のチュートリアルに沿って進めていけば大丈夫です。(人任せ2)
もう Mobile Engagement 作成は済んでいるので、キーをコピーするところ以降から。
Xamarin.iOS 用 Azure Mobile Engagement の使用
Xamarin.Forms プロジェクトに Mobile Engagement 接続(UWP 編)
基本的に以下のチュートリアルに沿って進めていけば大丈夫です。(人任せ3)
もう Mobile Engagement 作成は済んでいるので、キーをコピーするところ以降から。
Windows ユニバーサル アプリの Azure Mobile Engagement の概要
- 【注意1】UWP は他と NuGet のパッケージが違うから注意(~Xamarin ではない)
- 【注意2】リンク先にも書いてありますが、NuGet は、Windows 10 UWP アプリケーションで SDK のリソースを自動的にコピーしません。 NuGet パッケージのインストール時に表示される手順 (readme.txt) に従って、手動で行う必要があります。
とあります。readme.txtの内容は以下の通り。はい。自分で作れっつーことですね。
NuGet does not automatically copy the SDK resources in your Windows 10 UWP application. You have to do it manually until the scaffolding feature is reintroduced. Here are the steps for a new integration: * Open your File Explorer. * Navigate to the following location: %USERPROFILE%\.nuget\packages\MicrosoftAzure.MobileEngagement\3.4.1\content\win81 * Drag and drop the "Resources" folder from the file explorer to the root of your project in Visual Studio. * In Visual Studio select your project and activate the "Show All files" icon on top of the "Solution Explorer". * Some files may not be included in the project. To import them at once right click on the "Resources" folder, "Exclude from project" then another right click on the "Resources" folder, "Include in project" to re-include the whole folder. All files from the "Resources" folder are now included in your project.
まとめ
この辺までの基本的な設定 + PCL に interface 作って各プラットフォーム側で処理を追加して PCL の MainPage.xaml.cs にアクティブにする処理入れたヤツを以下のリポジトリにアップしてあります。
github.com
Mobile Engagement 側の接続文字列を設定すればとりあえず動くと思います。
Push 通知したい場合は各プラットフォームのリンク先を参考に設定してみてください。(最後も人任せ)
それではお疲れ様でした。
VSTS で Team Foundation Version Control で Xamarin のソース管理をする際に package フォルダーを除外したい
かなりニッチな投稿です。
Visual Studio Team Services(VSTS)でソース管理を行う場合、以下の2つから選択できます。
- Git(分散型バージョン管理システム)
- Team Foundation Version Control(集中型バージョン管理システム)
正直 Git が今は主流だと思うのですが、ウチのチームは旧 Visual Source Safe(VSS)からの名残で Team Foundation Server(TFS) ベースの方を利用しています。
Xamarin.Forms のテンプレートで作ったプロジェクトを上記ソース管理に追加をすると、管理対象に package フォルダーを追加してしまいます。
もちろんこのチェックインからは除外することはできるのですが、永続的に対象から除外することは Visual Studio のメニューからはできなそうでした。
Xamarin が悪いのか、Visual Studio が悪いのか VSTS が悪いのか、それともほかの要因なのかわかりませんが。
チームで作業している場合、package フォルダーがソース管理されてしまうと、各作業者がビルドする時に NuGet からパッケージをダウンロードしてくる時に競合したり、読み取り専用になってるからエラーになったり、作業者が別のソースをチェックインしようとすると一緒にわんさか「こいつも変更しとるな?チェックインするけ?」と聞かれて毎回除外する必要がありとても面倒でした。
除外方法
ソリューションと同階層に以下のフォルダ/ファイルを置くだけ
・.tfignore ファイル
・.nuget フォルダ
・NuGet.config ファイル
.tfignore ファイルの中身
除外したいフォルダやファイルのパスを記載するだけ
今回なら
\package
NuGet.config ファイルの中身
<?xml version="1.0" encoding="utf-8"?> <configuration> <solution> <add key="disableSourceControlIntegration" value="true" /> </solution> </configuration>
Tech Summit の資料・動画が公開されました
shunsukekawai.hatenablog.com
↑こちらで登壇した旨を記載しましたが、資料、動画が公開されました。
【Xamarin 開発の真実】 Microsoft Tech Summit で登壇してきました!
11/1,2 で開催された Microsoft Tech Summit でテクニカルスポンサー枠として登壇してきました。
弊社は Mobile 系の開発や Windows 系の開発を推進してきた経緯もあり、今回 日本マイクロソフト株式会社 様より Xamarin でイベントアプリ開発のご依頼を受け、その流れで登壇をさせていただきました。
講演内容
【Xamarin 開発の真実】イベントアプリの中身、すべてお見せします
と名前負けしそうなタイトルとなりましたが、主な内容としては以下の通りです。
- Xamarin とは
- イベントアプリの構成
- Xamarin と UX
- Xamarin と認証
- Xamarin と Push 通知 + α
それぞれどんなことを話したか簡単にまとめます。
Xamarin とは
このサイト見てくださいw
www.jmas.co.jp
イベントアプリの構成
イベントアプリの構成はこんな感じですー。ってそのままの話です。
サーバーは別の会社さんが開発をしていて、そこにアプリから接続してデータのやり取りをしています。
Xamarin と UX
標準だけでいけると思ってましたがやはりカスタマイズが必要になったので、Custom Renderer や Effects を利用しなきゃダメだよってお話し。
Xamarin と 認証
イベントアプリでは Microsoft アカウントでのサインインをする必要があります。
認証機能をどうやって作っているのか、デモを交えて説明しました。
詳細はここを参照ください。
blog.xamarin.com
Xamarin と Push 通知 + α
Azure Mobile Engagement を利用して Push 通知やユーザー状況の確認、クラッシュログなどが簡単に利用できるってお話し。
こんな感じでアクティブなユーザー数がリアルタイムで表示されます。
どの画面がよく使われているかをグラフィカルに表示してくれます。
詳細はここを参照ください。
azure.microsoft.com
※上記リンクは Xamarin.Android 用 & ちょっと古いので、変更が必要な箇所があります。
Azure Mobile Engagement を使ってみて
セッション中も参加者の方々にご協力いただき、アプリをアクティブにしていただいてリアルタイムに数がぐーんと上がるのをお見せしましたが、あんな機能を数行のコードで実現できてしまうのはホントにスゴイと思います。
Push 通知も簡単に管理できます!(デモでは失敗しましたが…)
マーケティングの方にすごい喜ばれる機能が盛りだくさんな感じです。
是非お試しください!!
azure.microsoft.com
Visual Studio から 作成した iOS の ipa をアプリケーションローダーに喰わせると ITMS-90023 が発生する
Xamarin で開発して iOS の AppStore にアップロードするための ipa を作成する際にアプリケーションローダーを使用してます。
Visual Studio の Xamarin.Forms のテンプレートから作ったプロジェクトをそのままアップロードすると以下のエラーが発生します。
ERROR ITMS-90023: "Missing required icon file. The bundle does not contain an app icon for iPad of exactly '167x167' pixels, in .png format for iOS versions supporting iPad Pro."
対応方法
Info.plist を XML エディター等で開きます。
その中のアイコンの指定が並んでいる箇所を選択して
<array> <string>Icon-72@2x.png</string> <string>Icon-72.png</string> <string>Icon@2x.png</string> <string>Icon.png</string> <string>Icon-60@2x.png</string> <string>Icon-76.png</string> <string>Icon-76@2x.png</string> <string>Default.png</string> <string>Default@2x.png</string> <string>Default-568h@2x.png</string> <string>Default-Portrait.png</string> <string>Default-Portrait@2x.png</string> <string>Icon-Small-50@2x.png</string> <string>Icon-Small-50.png</string> <string>Icon-Small-40.png</string> <string>Icon-Small-40@2x.png</string> <string>Icon-Small.png</string> <string>Icon-Small@2x.png</string> </array>
の中に
<string>Icon-83.5@2x.png</string>
を追加します。
あとは対応するサイズ(167x167)のアイコンを追加すればOKです。
注意点
Visual Studio 上で iOS のプロジェクトのプロパティを編集(プロビジョニングファイル等の設定を編集)して保存すると上記のplistの設定が勝手に消えますw
なので、申請用 ipa を作成する際にはちゃんと確認した方がいいかもですね。。
追記
田淵さん(@ytabuchi)に教えていただいた方法の方が楽ちんですね。
ytabuchi.hatenablog.com
(おそらく)世界一簡単にXamarin.Formsのアプリに特定の値でQRコードを生成して表示する方法
public MainPage() { var QrValue = "QRコードにしたい文字列"; var imgQr = new Image { Aspect = Aspect.AspectFit }; imgQr.Source = ImageSource.FromUri(new Uri($"http://chart.apis.google.com/chart?cht=qr&chs=200x200&chld=H|0&chl={QrValue}")); Content = imgQr; }
以上!
というのも寂しいので、ちょっと解説です。
みなさんご存知の通り、XamarinにはURLを画像ソースに指定する機能があります。
developer.xamarin.com
それを利用してGoogleのQRコード生成のAPIを呼び出し、その結果を設定しているだけです。
QR Codes | Infographics | Google Developers
※Warning: This API is deprecated. Please use the actively maintained Google Charts API instead. See our deprecation policy for details.
ということで現在、このAPIは非推奨のようなのでいつ使えなくなるかわかりません。
また、非推奨になったことでライセンスもよくわかりませんでした。
なので自己責任でお願いします
画像として返却してくれるAPIであればこれでなくてもなんでも大丈夫だと思います。
さらにおまけで…
こんな感じでイメージコントロールとインジケーターを重ねておいてイメージの読み込みが完了するまでぐるぐるが表示されるようにするといい感じですね。
(このAPIからのレスポンスが一瞬なのでぐるぐるが見えることはないかもしれません。。。)
public MainPage() { var QrValue = "QRコードにしたい文字列"; var imgQr = new Image { Aspect = Aspect.AspectFit }; imgQr.Source = ImageSource.FromUri(new Uri($"http://chart.apis.google.com/chart?cht=qr&chs=200x200&chl={QrValue}")); var prgIndicator = new ActivityIndicator{ HorizontalOptions = LayoutOptions.CenterAndExpand, VerticalOptions = LayoutOptions.CenterAndExpand }; imgQr.PropertyChanged += (sender, e) => { if (e.PropertyName != nameof(imgQr.IsLoading)) return; prgIndicator.IsRunning = imgQr.IsLoading; prgIndicator.IsVisible = imgQr.IsLoading; }; Content = new Grid { Children = { prgIndicator, imgQr } }; }
Xamarin.FormsでUWPをReleaseビルドすると埋め込みリソースの画像が表示されない
以下の環境でUWPをReleaseビルドするとPCL側に配置した埋め込みリソースの画像が表示されませんでした。
・Xamarin.Forms 2.3.1.114
・VisualStudio 2015 Enterprise Update 3
・UWP対象ターゲット 10586
Xamarin.Formsで画像を表示する際に全プラットフォームで共通の画像を使いまわしたい場合、埋め込みリソースを使用する場合があると思います。
画像の設定方法については公式を参照ください。
developer.xamarin.com
んで、埋め込みリソースを使っていて、かつUWPのReleaseビルド(ビルドプロパティの「.Net ネイティブ ツール チェーンでコンパイルする」にチェックついている状態)で作成したアプリを実行するとデバッグコンソールに以下のエラーが出力されて画像が表示されませんでした。
例外がスローされました: 'System.IO.FileNotFoundException' (System.Private.Reflection.Core.dll の中)
んで、対症療法です。(解決方法と書いていいか自信ない…)
というか、こうやったらできた。
画像のパスを設定する際にAssemblyを引数に加えてやると表示されるようになりました。
var assembly = typeof(App).GetTypeInfo().Assembly; img.Source = ImageSource.FromResource("XamarinApp1.Images.xamarin.png", assembly);
.Net Nativeさん怖い…
Androidでアプリアンインストール時の確認メッセージに「~は次のアプリの一部です」と出てくる
(Android開発に慣れている人は当たり前のことなのかもしれませんが)
Xamarin.Formsでデフォルトの設定で作成したアプリをアンインストールをしようとすると、以下のように謎の確認メッセージがでてきます。
(Android 5以降で確認)
変ですよね。
普通のアプリはこんな感じになります。
それで直し方。
アプリの名前なので、AndroidManifestの記載とMainActivity.csの記載を一致させると期待する結果になりました。
結果
上の例はテスト用の命名でしたが、通常の開発だとプロジェクトの命名にスペースは普通入れないけど、アプリの命名にはスペース入れるってケースは多いと思います。
その場合、MainActivity側を修正しないといけないって点がちょっとハマりました…
(MainActivityの記載はプロジェクト作成時に勝手に作成されて、かつ違いがスペースの有無だけなので…)
"ConvertResourcesCases" タスクが予期せずに失敗しました。
備忘
Xamarinでソリューションのファイルに日本語のパスが含まれているとAndroidのビルド時にタイトルのエラーが出る。
ユーザー名が日本語だと意図せず日本語パスが含まれる可能性もあるから要注意。
エラー "ConvertResourcesCases" タスクが予期せずに失敗しました。
System.IO.DirectoryNotFoundException: パス 'C:\Users\kawai\Documents\Visual Studio 2015\Projects\XamarinTestApp縺・XamarinApp\XamarinApp.Droid\obj\Debug\__library_projects__\Xamarin.Forms.Platform.Android\library_project_imports\res' の一部が見つかりませんでした。
場所 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
場所 System.IO.FileSystemEnumerableIterator`1.CommonInit()
場所 System.IO.FileSystemEnumerableIterator`1..ctor(String path, String originalUserPath, String searchPattern, SearchOption searchOption, SearchResultHandler`1 resultHandler, Boolean checkHost)
場所 System.IO.Directory.EnumerateDirectories(String path, String searchPattern, SearchOption searchOption)
場所 Xamarin.Android.Tasks.ConvertResourcesCases.FixupResources(ITaskItem item, Dictionary`2 acwMap)
場所 Xamarin.Android.Tasks.ConvertResourcesCases.FixupResources(Dictionary`2 acwMap)
場所 Xamarin.Android.Tasks.ConvertResourcesCases.Execute()
場所 Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute()
場所 Microsoft.Build.BackEnd.TaskBuilder.d__26.MoveNext() XamarinApp.Droid
Android only allows one navigation page on screen at a time
備忘
Xamarin.FormsのAndroid実行でタイトルのようなエラーが出たら、
だめ
public App() { MainPage = new NavigationPage(new MediaPage()); }
だいじょうぶ
public App() { MainPage = new MainPage(); }
UWPでカメラを使う際の注意点
UWPでカメラを使ったアプリを作る場合、一番簡単なのは CameraCaptureUI を使用した方法です。
細かい使い方はMSDN参照↓
CameraCaptureUI を使った写真とビデオのキャプチャ - Windows app development
この方法であればマニフェストファイルを「Webカメラ」の宣言も不要なままカメラを使えます。
ただ、この方法だと「アプリケーションのテンポラリーフォルダ(ms-appdata:///temp/)」に「CCapture.png」というファイル名でファイルがドンドン溜まっていきます。
なので、気付いたら保存した覚えのない写真がいつまでも残っちゃうなんてことがあるので要注意です。
ファイルにしたくない、細かい設定がしたい、とかの場合は MediaCapture を使用する方がよいみたいです。
MSDN サブスクリプション ユーザーのXamarin登録方法
XamarinがVisualStudioユーザーに無料でついてくるようになりTLがその話題で持ち切りですが、実際にアクティベーションする方法がわかりづらく、また、どこにも書いてなかったのでメモ。
<前提>
Visual Studio Enterprise with MSDN のライセンスの場合です。
その他のサブスクリプションに関してはわかりません。
① MSDNのサブスクリプションのページへ行きます。
https://msdn.microsoft.com/ja-jp/subscriptions/manage
② アカウントタブの「Xamarin Studio (for OS X)」の「Register and download」を選択
③ Xamarinの登録ページに飛ぶので必要事項を記入して登録!!!
無料だーー!
GridView(ListView)のアイテムを選択した時に凹む動作をやめたい
UWPでGridViewもしくはListViewをただ単にパネルとしてボタンとかのコントロールを置いて使いたいケースがありました。
UWPから標準のGridViewItemはPressed時に押した箇所が凹むアニメーションが勝手に入ります。
それがちょっと用途からして邪魔だったので消しました。
MSDNのページからスタイルをコピーしてきて、、
GridViewItem スタイルとテンプレート - Windows app development
悪さをしそうなStoryboardを消してきます。
根本はこいつですね↓
PointerDownThemeAnimation
ついでにPointerOver時に枠に色が付くのとかも消しました。
こんな感じ↓
XAML
一応アイテムクリックが動くのか、アイテムの中のボタンは動くのかの確認用のイベント入れてます。
<GridView IsItemClickEnabled="True" ItemClick="GridView_ItemClick"> <!--動くGridViewItem--> <GridViewItem> <StackPanel Width="300" Height="300"> <StackPanel.Background> <ImageBrush Stretch="Fill" ImageSource="Assets/saru.PNG"/> </StackPanel.Background> <TextBlock FontSize="30" Text="動くGridViewItem" /> <Button Click="Button_Click" Content="テストボタン" /> </StackPanel> </GridViewItem> <!--動かないGridViewItem--> <GridViewItem Style="{StaticResource DisableEffectGridViewItemStyle}"> <StackPanel Width="300" Height="300"> <StackPanel.Background> <ImageBrush Stretch="Fill" ImageSource="Assets/saru.PNG"/> </StackPanel.Background> <TextBlock FontSize="30" Text="動かないGridViewItem" /> <Button Click="Button_Click" Content="テストボタン" /> </StackPanel> </GridViewItem> </GridView>
Style
<Style x:Key="DisableEffectGridViewItemStyle" TargetType="GridViewItem"> <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" /> <Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" /> <Setter Property="Background" Value="Transparent" /> <Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}" /> <Setter Property="TabNavigation" Value="Local" /> <Setter Property="IsHoldingEnabled" Value="True" /> <Setter Property="HorizontalContentAlignment" Value="Center" /> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="Margin" Value="0,0,4,4" /> <Setter Property="MinWidth" Value="{ThemeResource GridViewItemMinWidth}" /> <Setter Property="MinHeight" Value="{ThemeResource GridViewItemMinHeight}" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="GridViewItem"> <Grid x:Name="ContentBorder" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="CommonStates"> <VisualState x:Name="Normal"> <Storyboard> <PointerUpThemeAnimation Storyboard.TargetName="ContentPresenter" /> </Storyboard> </VisualState> <VisualState x:Name="PointerOver" /> <VisualState x:Name="Pressed" /> <VisualState x:Name="Selected" /> <VisualState x:Name="PointerOverSelected" /> <VisualState x:Name="PressedSelected" /> </VisualStateGroup> <VisualStateGroup x:Name="DisabledStates"> <VisualState x:Name="Enabled" /> <VisualState x:Name="Disabled"> <Storyboard> <DoubleAnimation Duration="0" Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="Opacity" To="{ThemeResource ListViewItemDisabledThemeOpacity}" /> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="FocusStates"> <VisualState x:Name="Unfocused" /> <VisualState x:Name="Focused"> <Storyboard> <DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualWhite" Storyboard.TargetProperty="Opacity" To="1" /> <DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisualBlack" Storyboard.TargetProperty="Opacity" To="1" /> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="MultiSelectStates"> <VisualState x:Name="MultiSelectDisabled"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> <DiscreteObjectKeyFrame KeyTime="0:0:0.333" Value="Collapsed" /> </ObjectAnimationUsingKeyFrames> <FadeOutThemeAnimation TargetName="MultiSelectSquare" /> </Storyboard> </VisualState> <VisualState x:Name="MultiSelectEnabled"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MultiSelectSquare" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> </ObjectAnimationUsingKeyFrames> <FadeInThemeAnimation TargetName="MultiSelectSquare" /> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="DataVirtualizationStates"> <VisualState x:Name="DataAvailable" /> <VisualState x:Name="DataPlaceholder"> <Storyboard> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextBlock" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderRect" Storyboard.TargetProperty="Visibility"> <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" /> </ObjectAnimationUsingKeyFrames> </Storyboard> </VisualState> </VisualStateGroup> <VisualStateGroup x:Name="ReorderHintStates"> <VisualState x:Name="NoReorderHint" /> <VisualState x:Name="BottomReorderHint"> <Storyboard> <DragOverThemeAnimation Direction="Bottom" ToOffset="{ThemeResource GridViewItemReorderHintThemeOffset}" TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualState x:Name="TopReorderHint"> <Storyboard> <DragOverThemeAnimation Direction="Top" ToOffset="{ThemeResource GridViewItemReorderHintThemeOffset}" TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualState x:Name="RightReorderHint"> <Storyboard> <DragOverThemeAnimation Direction="Right" ToOffset="{ThemeResource GridViewItemReorderHintThemeOffset}" TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualState x:Name="LeftReorderHint"> <Storyboard> <DragOverThemeAnimation Direction="Left" ToOffset="{ThemeResource GridViewItemReorderHintThemeOffset}" TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualStateGroup.Transitions> <VisualTransition GeneratedDuration="0:0:0.2" To="NoReorderHint" /> </VisualStateGroup.Transitions> </VisualStateGroup> <VisualStateGroup x:Name="DragStates"> <VisualState x:Name="NotDragging" /> <VisualState x:Name="Dragging"> <Storyboard> <DoubleAnimation Duration="0" Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="Opacity" To="{ThemeResource ListViewItemDragThemeOpacity}" /> <DragItemThemeAnimation TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualState x:Name="DraggingTarget"> <Storyboard> <DropTargetItemThemeAnimation TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualState x:Name="MultipleDraggingPrimary"> <Storyboard> <DoubleAnimation Duration="0" Storyboard.TargetName="MultiArrangeOverlayBackground" Storyboard.TargetProperty="Opacity" To="1" /> <DoubleAnimation Duration="0" Storyboard.TargetName="MultiArrangeOverlayText" Storyboard.TargetProperty="Opacity" To="1" /> <DoubleAnimation Duration="0" Storyboard.TargetName="ContentBorder" Storyboard.TargetProperty="Opacity" To="{ThemeResource ListViewItemDragThemeOpacity}" /> <FadeInThemeAnimation TargetName="MultiArrangeOverlayBackground" /> <FadeInThemeAnimation TargetName="MultiArrangeOverlayText" /> <DragItemThemeAnimation TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualState x:Name="MultipleDraggingSecondary"> <Storyboard> <FadeOutThemeAnimation TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualState x:Name="DraggedPlaceholder"> <Storyboard> <FadeOutThemeAnimation TargetName="ContentBorder" /> </Storyboard> </VisualState> <VisualStateGroup.Transitions> <VisualTransition GeneratedDuration="0:0:0.2" To="NotDragging" /> </VisualStateGroup.Transitions> </VisualStateGroup> </VisualStateManager.VisualStateGroups> <ContentPresenter x:Name="ContentPresenter" Margin="{TemplateBinding Padding}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" ContentTransitions="{TemplateBinding ContentTransitions}" /> <TextBlock x:Name="PlaceholderTextBlock" Margin="{TemplateBinding Padding}" AutomationProperties.AccessibilityView="Raw" Foreground="{x:Null}" IsHitTestVisible="False" Text="Xg" Visibility="Collapsed" /> <Rectangle x:Name="PlaceholderRect" Fill="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" Visibility="Collapsed" /> <Rectangle x:Name="MultiArrangeOverlayBackground" Grid.ColumnSpan="2" Fill="{ThemeResource ListViewItemDragBackgroundThemeBrush}" IsHitTestVisible="False" Opacity="0" /> <Rectangle x:Name="BorderRectangle" IsHitTestVisible="False" Opacity="0" Stroke="{ThemeResource SystemControlHighlightListAccentLowBrush}" StrokeThickness="2" /> <Border x:Name="MultiSelectSquare" Width="20" Height="20" Margin="0,2,2,0" HorizontalAlignment="Right" VerticalAlignment="Top" Background="{ThemeResource SystemControlBackgroundChromeMediumBrush}" Visibility="Collapsed"> <FontIcon x:Name="MultiSelectCheck" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="16" Foreground="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" Glyph="" Opacity="0" /> </Border> <Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" Opacity="0" Stroke="{ThemeResource SystemControlForegroundAltHighBrush}" StrokeDashArray="1.0, 1.0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" StrokeThickness="2" /> <Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" Opacity="0" Stroke="{ThemeResource SystemControlForegroundBaseHighBrush}" StrokeDashArray="1.0, 1.0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" StrokeThickness="2" /> <TextBlock x:Name="MultiArrangeOverlayText" Grid.ColumnSpan="2" Margin="18,9,0,0" AutomationProperties.AccessibilityView="Raw" FontFamily="{ThemeResource ContentControlThemeFontFamily}" FontSize="26.667" Foreground="{ThemeResource ListViewItemDragForegroundThemeBrush}" IsHitTestVisible="False" Opacity="0" Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=TemplateSettings.DragItemsCount}" TextTrimming="WordEllipsis" TextWrapping="Wrap" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>
Slackでよく使うショートカットとか
メモメモ
Alt + クリック : 既読→未読
入力領域で↑ : 直近の自分の投稿を再編集する
``` で囲む : 囲ったところを引用
> (半角) : その行を引用