表示方向変更プラグイン for 提督業も忙しい!をリリースしました。
提督業も忙しい!の情報表示場所を左右上下、好きな場所に変更できます。
設定は保存されるので、起動するたびに表示方向を設定する必要はありません!
ダウンロードはこちらからどうぞ。
表示方向変更プラグイン for 提督業も忙しい!をリリースしました。
提督業も忙しい!の情報表示場所を左右上下、好きな場所に変更できます。
設定は保存されるので、起動するたびに表示方向を設定する必要はありません!
ダウンロードはこちらからどうぞ。
WPFアプリケーションを作ってて「ウィンドウがモニタの端にスナップ(吸い付くように自動で移動)してほしい!」っていうあなた!
そんな簡単に時に使えるビヘイビアです。
スナップ距離やスナップ有効・無効の設定のバインディングもできます。
あとモニタの表示倍率が100%でないときでも動作します(たぶん)。
WPFなのにSystem.Windows.Forms.dllとSystem.Drawing.dllを参照する必要がありなんだか負けた気がしますが、気にしないでいきましょう。
class WindowSnapBehavior : Behavior<Window>
{
#region EnableSnap 依存関係プロパティ
public double SnapDistance
{
get { return (double)GetValue(SnapDistanceProperty); }
set { SetValue(SnapDistanceProperty, value); }
}
public static readonly DependencyProperty SnapDistanceProperty =
DependencyProperty.Register("SnapDistance", typeof(double), typeof(WindowSnapBehavior), new PropertyMetadata(7.0));
#endregion
#region EnableSnap 依存関係プロパティ
public bool EnableSnap
{
get { return (bool)GetValue(EnableSnapProperty); }
set { SetValue(EnableSnapProperty, value); }
}
public static readonly DependencyProperty EnableSnapProperty =
DependencyProperty.Register("EnableSnap", typeof(bool), typeof(WindowSnapBehavior), new PropertyMetadata(true));
#endregion
protected override void OnAttached()
{
AssociatedObject.LocationChanged += AssociatedObject_LocationChanged;
}
protected override void OnDetaching()
{
AssociatedObject.LocationChanged -= AssociatedObject_LocationChanged;
}
void AssociatedObject_LocationChanged(object sender, EventArgs e)
{
if (!EnableSnap) { return; }
var window = AssociatedObject;
if (window.WindowState != WindowState.Normal) { return; }
// DPIから物理ピクセルへ変換する行列を取得してそれぞれの長さを変換
var mat = PresentationSource.FromVisual(window).CompositionTarget.TransformToDevice;
var scaledTopLeft = mat.Transform(new Point(window.Left, window.Top));
var scaledBottomRight = mat.Transform(new Point(window.Left + window.ActualWidth, window.Top + window.ActualHeight));
var scaledSnapDisatance = mat.Transform(new Point(SnapDistance, SnapDistance));
var scaledSize = scaledBottomRight - scaledTopLeft;
var screen = System.Windows.Forms.Screen.FromPoint(new System.Drawing.Point((int)scaledTopLeft.X, (int)scaledTopLeft.Y));
var newTop = scaledTopLeft.Y;
var newLeft = scaledTopLeft.X;
// 横方向の調整
if (Math.Abs(screen.Bounds.Left - scaledTopLeft.X) <= scaledSnapDisatance.X) {
newLeft = screen.Bounds.Left;
}
else if (Math.Abs(screen.Bounds.Right - scaledBottomRight.X) <= scaledSnapDisatance.X) {
newLeft = screen.Bounds.Right - scaledSize.X;
}
// 縦方向の調整
if (Math.Abs(screen.Bounds.Top - scaledTopLeft.Y) <= scaledSnapDisatance.Y) {
newTop = screen.Bounds.Top;
}
else if (Math.Abs(screen.Bounds.Bottom - scaledBottomRight.Y) <= scaledSnapDisatance.Y) {
newTop = screen.Bounds.Bottom - scaledSize.Y;
}
window.Left = newLeft;
window.Top = newTop;
}
}
使う時はこんな感じです。
<Window x:Class="Studiotaiha.SnapTest.Views"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:behaviors="clr-namespace:Studiotaiha.SnapTest.Views.Behaviors"
Title="SnapTest">
<i:Interaction.Behaviors>
<behaviors:WindowSnapBehavior />
</i:Interaction.Behaviors>
<Grid>
<TextBlock>コンテンツ</TextBLock>
</Grid>
</Window>
実際に使う時はPresentationSourceの取得に失敗したりするかもしれないので、エラー処理は忘れずに。
画面分離プラグイン for 提督業も忙しい!をリリースしました。
各種情報表示部をウィンドウとして分離できるほか、キャプションバーに表示切り替えボタンを配置して手軽に表示切り替えを行えます。
ダウンロードはこちらからどうぞ。
資材統計プラグイン for 抵当業も忙しい!を公開しました。
資材推移のグラフ表示などを行います。
ダウンロードはこちらからどうぞ!
あと、スタジオ大破のWebサイトも更新しました。
http://www.studio-taiha.net/
提督業も忙しい!をモニタの端にスナップできる「画面スナッププラグイン for 提督業も忙しい!」を公開しました。
ダウンロードや詳細は以下をご覧ください。
画面スナッププラグイン for 提督業も忙しい!
XAML Advent Calender 2014 12日目の記事です。
Advent Calenderで連載物なんて載せちゃって怒られそうな気がしなくもなくなくないですが、今回は前回「Xamarin.Formsでカメラを使う – Android編」に引き続きXamarin.FormsでWindows Phone 8のカメラを使う方法をご紹介します。
恐縮ですが、この記事を読む前に前回の記事をお読みください。
なおサンプルプログラムをGithubで公開しています。
完全なコードは、こちらをご覧ください。
まずCustomeRendererとCameraPreviewクラスを前回の記事に従い、PCLプロジェクトに作成します。
WP8用のプロジェクトでは、WP8に特化したViewRendererのサブクラスを作成します。
前回の記事にも書いたように、Generic版のViewRendererを利用するため、WP8のプロジェクトで参照しているXamarin.Forms.dllをVersion 1.2.2.*以降にアップデートする必要があります。
NuGetパッケージマネージャから更新しましょう。

Xamarin.Forms.Platform.WinPhone.ViewRenderer
TViewにはPCL内で定義したCameraPreviewクラス、TNativeViewにはカスタムレンダラで実際に表示させるプラットフォーム固有のViewを指定します。
今回はContentControlをこのNativeViewとし、その中にViewBoxコントロール,Canvasコントロールを配置し、Canvasコントロールに映し出したカメラのプレビュー画像を自動でリサイズできるように実装します。
XAMLで書くとこんな感じです。
<ContentControl> <ViewBox> <Canvas /> </ViewBox> </ContentContro>
ViewBoxの外側にContentControlを置いておかないとViewBoxのリサイズがうまく働かないので注意してください。
XAML Advent CalenderらしくこのコントロールをXAMLで書くのもいいかとは思うのですが、今回は簡略化のためcsのコードのみで実装します。
public class CameraPreviewRenderer : ViewRenderer<CameraPreview, ContentControl>
{
Canvas canvas_ = null;
CameraPreview cameraPreview_ = null;
PhotoCamera camera_ = null;
public CameraPreviewRenderer()
{
// コントロールのイベントハンドラを設定
// コントロールがロードされたとき・アンロードされたときのイベント
Loaded += CameraPreviewRenderer_Loaded;
Unloaded += CameraPreviewRenderer_Unloaded;
}
protected override void OnElementChanged(ElementChangedEventArgs<CameraPreview> e)
{
base.OnElementChanged(e);
// 最初に生成された時だけここを通る
if (e.OldElement == null) {
cameraPreview_ = e.NewElement; // CameraPreviewオブジェクトを取得
// コントロールを作成
var contentControl = new ContentControl();
// ViewBoxを作成
var viewBox = new Viewbox() {
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch,
VerticalAlignment = System.Windows.VerticalAlignment.Stretch,
Stretch = System.Windows.Media.Stretch.Uniform
};
// カメラプレビューをを写すためのCanvasを作成
canvas_ = new Canvas();
// ContentControl - ViewBox - Canvas となるよう親子関係を構築
viewBox.Child = canvas_;
contentControl.Content = viewBox;
// ContentControlをNativeViewとして設定
SetNativeControl(contentControl);
// CameraPreviewクラスの写真要求イベントを登録
cameraPreview_.PictureRequired += cameraPreview_PictureRequired;
}
}
/// <summary>
/// 写真要求イベントのコールバック
/// </summary>
void cameraPreview_PictureRequired(object sender, EventArgs e)
{
if (camera_ != null) {
// 写真撮影命令発行
camera_.CaptureImage();
}
}
/// <summary>
/// コントロールがロードされた時のコールバック
/// </summary>
void CameraPreviewRenderer_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
// カメラを初期化
try {
camera_ = new PhotoCamera(CameraType.Primary); // 失敗すると例外が飛ぶ
}
catch {
camera_ = null;
}
if (camera_ != null) {
// canvasにPreviewBrushを設定し、canvasの大きさをプレビュー画像に合わせる
var previewResolution = camera_.PreviewResolution;
canvas_.Width = previewResolution.Width;
canvas_.Height = previewResolution.Height;
var videoBrush = new System.Windows.Media.VideoBrush();
videoBrush.SetSource(camera_);
canvas_.Background = videoBrush;
// 写真撮影に成功したときのコールバックを設定
camera_.CaptureImageAvailable += camera__CaptureImageAvailable;
}
}
/// <summary>
/// コントロールがアンロードされたときのコールバック
/// </summary>
void CameraPreviewRenderer_Unloaded(object sender, System.Windows.RoutedEventArgs e)
{
// カメラを破棄
if (camera_ != null) {
var camera = camera_;
camera_ = null;
camera.Dispose();
}
}
/// <summary>
/// 写真が撮影された時のコールバック
/// </summary>
void camera__CaptureImageAvailable(object sender, ContentReadyEventArgs e)
{
// CameraPreviewクラスに撮影された写真を渡す
var image = new Models.WPImage {
ImageSource = ImageSource.FromStream(() => e.ImageStream)
};
cameraPreview_.OnPictureTaken(image);
}
}
コントロールが初期化されるタイミングでCameraを初期化し、CameraPreviewクラスより写真撮影要求が発行されたときに写真撮影命令を発行、写真撮影が完了したらCameraPreviewのOnPictureTaken()を呼び出しその旨を通知しています。
ViewRenderer.LoadedイベントとViewRenderer.Unloadedイベントがポイントで、このタイミングでCameraの初期化・破棄を行うことで、Xamarin.FormsのViewのライフサイクルに合わせたリソースの取得・確保ができます。
カスタムレンダラを実装したら、Xamarin.Forms.ExportRendererAttribute 属性を用いて作成したカスタムレンダラをExportします。
前回と同じく、以下の一行をコードの先頭部分などに記述するだけです。
[assembly: ExportRenderer(typeof(CameraPreview), typeof(XamarinFormsCameraPreview.WinPhone.Renderers.CameraPreviewRenderer))]
これで、カスタムレンダラの実装は完了です。
作成したカスタムレンダラを利用してカメラのプレビューを表示させるのですが、実はこの時点で前回作成したPLCプロジェクトを全く変更せず、WP8においてもカメラプレビューを表示できます。
実際にアプリケーションを動かして動作を確認してみましょう。
WP8のエミュレータ上でアプリケーションを起動すると、次のようにプレビューが表示されます。

TakePictureボタンをタップするとその場で写真が撮影され、以下の撮影写真プレビュー画面へ遷移します。

正常に写真が撮影され、画像として取得できていることが確認できました。
前回に引き続きXamarin.Formsを利用しWindows Phone 8でカメラプレビュー画像を表示しました。
本記事ではWindows Phone 8用プロジェクトにWindows Phone 8用のCameraPreviewRendererを実装したのみで、PLCプロジェクトは前回と全く同じ物を利用しています。
このあたりはCustom Rendererの高い抽象度とその利便性がわかります。Xamarin.Forms万歳です。直接WinRT叩けよという異論は認めます。
艦これのマスタデータをKancolleData.xmlとして出力できる、提督業も忙しい!向けプラグインを公開しました。
ダウンロードは以下からどうぞ。
KancolleDataXml出力プラグイン for 提督業も忙しい!
ここからはプラグインについて簡単な説明です。