Quantcast
Channel: かずきのBlog@hatena
Viewing all 1388 articles
Browse latest View live

ReactivePropertyオーバービューを更新しました。

$
0
0

blog.okazuki.jp

「そのほかにも」という箇所から簡単にですが、ReactivePropertyで追加しているIObservableの拡張メソッドで、紹介していないものを書いてみました。


Prism.WpfのApp.configによるModuleCatalogの構成の仕方をPrism自習用リポジトリに追加しました

$
0
0

Prism Template Packを使うと簡単にApp.configによるModuleCatalogの構成ができるということで、今まで書いてなかったそこの部分についてPrism自習用リポジトリに追記しました。

github.com

Xamarin版PrismのDependencyServiceサポート機能

$
0
0

Prism.Formsは、基本的にUnity(DIコンテナのほう)を使ってます。 こいつを使うとインスタンスの組み立てとかをお任せ出来るので楽ちんなのです!

Prism.Formsでは、そんなUnityの機能を拡張して、DependencyServiceから取得するインスタンスを自動でインジェクションしてくれる機能を提供しています。

従来

普通はDependencyServiceを使うときは以下のような手順になります。

インターフェースの作成

まず、PCLの所にインターフェースを定義します。ここではプラットフォームの名前を返すインターフェースみたいなのを作りました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace PrismUnityApp20.Models
{
    publicinterface IPlatformNameProvider
    {
        string GetName();
    }
}

各プラットフォームでの実装の作成

そして、次に各プラットフォームで実装を行います。 例えばAndroidだと以下のような感じですね。Dependency属性つけてるのがポイント。

using PrismUnityApp20.Models;
using Xamarin.Forms;

[assembly: Dependency(typeof(PrismUnityApp20.Droid.Models.AndroidPlatformNameProvider))]

namespace PrismUnityApp20.Droid.Models
{
    publicclass AndroidPlatformNameProvider : IPlatformNameProvider
    {
        publicstring GetName() => "Android";
    }
}

UWPだと以下のような感じ。

using PrismUnityApp20.Models;
using Xamarin.Forms;

[assembly: Dependency(typeof(PrismUnityApp20.UWP.Models.UWPPlatformNameProvider))]

namespace PrismUnityApp20.UWP.Models
{
    publicclass UWPPlatformNameProvider : IPlatformNameProvider
    {
        publicstring GetName() => "UWP";
    }
}

PCLでインスタンスを取得する

DependencyServiceのGetメソッドを使ってインスタンスを取得します。

var x = DependencyService.Get<IPlatformNameProvider>();
var name = x.GetName(); // メソッドを呼ぶと各プラットフォームの実装が呼ばれる

Prism.Formsの場合

最後のDependencyServiceのGetメソッドを呼ばなくてもよくなります。具体的には、使いたいクラスのコンストラクタの引数でインターフェースを受け取るようにするだけで自動的に各プラットフォーム固有の実装がインジェクションされます。

private IPlatformNameProvider PlatformNameProvider { get; }

public MainPageViewModel(INavigationService navigationService, IPlatformNameProvider pnp)
{
    // インスタンスをとっておいてよしなに使うthis.PlatformNameProvider = pnp;
}

こうすることのメリットは、なんといってもユニットテストが簡単になるという点ですね! テスト時には、Mock実装を簡単に差し込めるようになります。すばらし。

あと、個人的にGetメソッドかっこわるいと思ってたので、この機能は歓迎です。

JXUGC 13回で発表してきました #JXUG

Xamarin版PrismでViewとViewModelの紐づけルールを変える

$
0
0

PrismはデフォルトでViews名前空間にあるViewとViewModels名前空間にあるViewModelを紐づける機能を持っています。この機能を有効化するには、PageのXAMLに以下の2行を追加します。

xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"

ということで、Viewに対して属性でViewModelの型を指定するようにしてみたいと思います。これでViewに対して任意のViewModelを紐づけることができます。

まず、ViewModelを指定するための属性を定義します。

publicclass ViewModelAttribute : Attribute
{
    public Type ViewModelType { get; }

    public ViewModelAttribute(Type viewModelType)
    {
        this.ViewModelType = viewModelType;
    }
}

そして、AppクラスのConfigureViewModelLocatorをオーバーライドして以下のようなに記述します。

protectedoverridevoid ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();
    ViewModelLocationProvider.SetDefaultViewTypeToViewModelTypeResolver(viewType =>
    {
        var vm = viewType.GetTypeInfo().GetCustomAttribute<ViewModelAttribute>();
        return vm?.ViewModelType;
    });
}

ViewとViewModelの紐づけルールはViewModelLocationProviderのSetDefaultViewTypeToViewModelTypeResolverでラムダ式で指定します。ここでは、属性をとってきて、そのViewModelTypeで指定された型を返しています。

あとは、View側に以下のような感じでViewModelの型を指定すればOKです。

[ViewModel(typeof(MainPageViewModel))]
publicpartialclass MainPage : ContentPage
{
    public MainPage()
    {
        InitializeComponent();
    }
}

ReactivePropertyで自動でUIスレッドにイベント発行を変えるのを抑止する

$
0
0

普通はいいんですが、UWPとかでマルチウィンドウとか、共有コントラクトとか使うとUIスレッドが複数生成されて、UIスレッドが1つという前提に立ってるReactivePropertyだと、ちょっと嫌な感じになってしまいます。

そんなときは、Appクラスの初期化処理で以下の1行を追加すると、現在のスレッドでイベントが発行されるようになります。

// 余計なスレッド切り替えは自動でしないで
ReactivePropertyScheduler.SetDefault(CurrentThreadScheduler.Instance);

あとは、ViewModelあたりで明示的にSynchronizationContext.Currentを使ってObserveOnをしてやればUIスレッドに処理を移動させたり、もしくは、明示的にSynchronizationContextSchedulerを使ってReactiveProperty関係のクラスを作ればいいです。(明示的にSchedulerを指定する場合は、別にReactivePropertyScheduler.SetDefaultしなくても大丈夫。

// 現在のVMが今のUIスレッドでインスタンス化されること前提this.Time = new ReactiveProperty<string>(new SynchronizationContextScheduler(SynchronizationContext.Current));

ReactivePropertyで自動でUIスレッドにイベント発行を変えるのを抑止する その2

$
0
0

blog.okazuki.jp

上記記事では、ViewModelの中でSynchronizationContextSchedulerを作成していましたが、これだと単体テストが辛いということになります。これをいい感じにするには、ちょっと工夫がいるのですが…。例えばPrism.Unityを使うと以下のようにViewModelのコンストラクタの引数に渡すものを上書きすることができます。Unityの機能ですね。

具体的には、AppクラスでConfigureViewModelLocatorメソッドをoverrideして、ViewModelLocationProvider.SetDefaultViewModelFactoryの処理を置き換えることで対応可能です。

protectedoverridevoid ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();
    ViewModelLocationProvider.SetDefaultViewModelFactory(x => 
        this.Container.Resolve(x, 
            new ParameterOverride("scheduler", new SynchronizationContextScheduler(SynchronizationContext.Current))));
}

こうしておくと、ViewModelでは、以下のような引数を定義しておくだけでUIスレッドに紐づいたSchedulerが設定されてきます。

public MainPageViewModel(IScheduler scheduler)
{
    this.Time = new ReactiveProperty<string>(scheduler);

こうしておくと、単体テストでISchedulerをTestSchedulerに差し替えたりということが簡単にできるようになります。

C#で好きな機能

$
0
0

Blogネタが尽きたので小ネタを。

C#でプログラムする時によく使う便利機能を3つ挙げたいと思います。

async/await

やはりC#といったらこれですよね。 非同期処理を簡単に書ける。

blog.okazuki.jp

これがない言語でのプログラミングは、結構ストレスです。コールバック地獄になって。

文字列挿入

$使うやつですね。xxxFormat系メソッドを全て殺してしまうほどのインパクトがある。 これも地味によく使います。

ufcpp.net

null条件演算子

これのおかげでnullチェックをする機会がほとんどなくなりました。

blog.xin9le.net

地味にイベントを呼ぶときとかのnullチェックを省ける点や、LINQのFirstOrDefaultの後に続けて値を取得するときとかが楽でいいです。

ちなみにLINQは入らないの?

LINQは空気(なくてはならない)なので、わざわざ取り上げる機能ではない。


ReactivePropertyのコードスニペット

$
0
0

ReactivePropertyをインストールすると、地味にコードスニペットもNuGetパッケージ内に入ってます。ただインストールはされないので自分でインストールが必要です。

コードスニペットマネージャーからpackages/ReactiveProperty.2.x.x/Snippet/csharp6フォルダにある以下のファイルをインストールします。csharp5フォルダは、C#5.0向けです。

  • ReactiveCollection.snippet
  • ReactiveCommand.snippet
  • ReactiveCommandGeneric.snippet
  • ReactiveProperty.snippet
  • ReadOnlyReactiveCollection.snnipet
  • ReadOnlyReactiveProperty.snnipet

rpropでReactivePropertyの宣言が展開されます。rcommでReactiveCommand、rcommgでReactiveCommandのパラメータつき、rcollでReactiveCollection、rrcollでReadOnlyReactiveCollection、rrpropでReadOnlyReactivePropertyに対応しています。

例えばrpropと打ち込んでtab tabをすると以下のようなコードが展開されます。

public ReactiveProperty<T> PropertyName { get; }

まぁ、手で書いても大したことないコードですが、慣れると快適ではあります。

コードスニペットでちょっと快適になりましょう!

LINQのメソッド構文、クエリ式の構文

$
0
0

LINQってメソッド構文とクエリ式の構文の2つがあります。どっち使います?という話ですが個人的な見解として、メソッド構文がLINQの全機能にフルアクセスできるという点でメソッド構文を使用しています。 LINQのメソッド構文とクエリ式の構文の対応は以下のページにまとまっています。

Query Expression Syntax for Standard Query Operators

ちなみにクエリ式の構文のメリットとしては多段SelectManyが見やすいという点があります。

var a = from h in hoge
    from f in fuga
    from b in bar
    select new { h, f, b };

メソッド構文だとこういう感じになる。

var a = hoge.SelectMany(_ => fuga, (h, f) => new { h, f })
    .SelectMany(_ => bar, (hf, b) => new { hf.h, hf.f, b });

これの数がちょっと増えてくるとSelectManyのメソッド構文のほうがつらくなってきます。といっても、SelectManyを、超たくさん書くことって限られてるので、そんなに困ることはないです。

ということで、メソッド構文推しですよ!という話しでした。

Xamarin.FormsでInfragistics製コンポーネントのチャートコントロールを使ってみる

$
0
0

InfragisticsさんはXamarin.Forms向けのコントロールも提供しています。今時点だとチャート系コントロールを提供しているみたいなのでちょっと使ってみましょう。

Xamarin.Forms v2.0対応っぽいのでバージョンを2.2とかにあげてしまわないように注意が必要そうです。さて、まず、Portableのプロジェクトで以下のアセンブリを参照します。

  • InfragisticsXF
  • InfragisticsXF.Controls.Charts
  • InfragisticsXF.Controls.Barcodes
  • InfragisticsXF.Controls.Gauges

次に、Droidのプロジェクトで以下のアセンブリを追加します。

  • InfragisticsAndroidBindings.dll
  • InfragisticsXF.Android.dll
  • InfragisticsXF.Controls.Barcodes.Android.dll
  • InfragisticsXF.Controls.Charts.Android.dll
  • InfragisticsXF.Controls.Gauges.Android.dll

最後にiOSプロジェクトに以下のアセンブリを追加します。

  • InfragisticsXF.iOS.dll
  • InfragisticsXF.Controls.Barcodes.iOS.dll
  • InfragisticsXF.Controls.Charts.iOS.dll
  • InfragisticsXF.Controls.Gauges.iOS.dll
  • IG.Unified.dll
  • IGChart.Unified.dll

追加したらあとはデータを準備してバインドするだけです。今回はとりあえずこんな感じのPersonクラスと、それを性別ごとに集計したPiChartModelクラスを準備してます。

using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace App34.Models
{
    publicclass ChartApp
    {
        publicstatic ChartApp Default { get; } = new ChartApp();

        public ObservableCollection<Person> People { get; }

        public IEnumerable<PiChartModel> PiChartModels =>
            this.People
                .GroupBy(x => x.Sex)
                .Select(x => new PiChartModel
                {
                    Label = x.Key == 0 ? "男" : "女",
                    Value = x.Count(),
                });

        public ChartApp()
        {
            var r = new Random();
            this.People = new ObservableCollection<Person>(Enumerable.Range(1, 100)
                .Select(x => new Person
                {
                    Name = $"tanaka{x}",
                    Age = r.Next(50),
                    Sex = r.Next(2),
                }));
        }
    }

    publicclass Person : BindableBase
    {
        privateint age;

        publicint Age
        {
            get { returnthis.age; }
            set { this.SetProperty(refthis.age, value); }
        }

        privatestring name;

        publicstring Name
        {
            get { returnthis.name; }
            set { this.SetProperty(refthis.name, value); }
        }

        privateint sex;

        publicint Sex
        {
            get { returnthis.sex; }
            set { this.SetProperty(refthis.sex, value); }
        }

    }

    publicclass PiChartModel : BindableBase
    {
        privatestring label;

        publicstring Label
        {
            get { returnthis.label; }
            set { this.SetProperty(refthis.label, value); }
        }

        privateintvalue;

        publicint Value
        {
            get { returnthis.value; }
            set { this.SetProperty(refthis.value, value); }
        }

    }
}

ViewModelは、手抜きで、これらのデータを右から左にするだけです。すいません。

using App34.Models;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace App34.ViewModels
{
    publicclass MainPageViewModel : BindableBase
    {
        public ObservableCollection<Person> People => ChartApp.Default.People;

        public IEnumerable<PiChartModel> PiChartModels => ChartApp.Default.PiChartModels;
    }
}

あとは、Infragisticsのコントロールにバインドするだけです。

<?xml version="1.0" encoding="utf-8"?><ContentPage xmlns="http://xamarin.com/schemas/2014/forms"xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"xmlns:ig="clr-namespace:Infragistics.XF.Controls;assembly=InfragisticsXF.Controls.Charts"xmlns:ViewModels="clr-namespace:App34.ViewModels;assembly=App34"x:Class="App34.Views.MainPage"><ContentPage.BindingContext><ViewModels:MainPageViewModel /></ContentPage.BindingContext><Grid><Grid.RowDefinitions><RowDefinition /><RowDefinition /></Grid.RowDefinitions><ig:XFDataChart><ig:XFDataChart.Axes><ig:CategoryXAxis x:Name="xAxis"ItemsSource="{Binding People}"Label="Name"LabelAngle="45"/><ig:NumericYAxis  x:Name="yAxis" /></ig:XFDataChart.Axes><ig:XFDataChart.Series><ig:AreaSeries ItemsSource="{Binding People}"ValueMemberPath="Age"XAxis="{x:Reference xAxis}"YAxis="{x:Reference yAxis}"></ig:AreaSeries></ig:XFDataChart.Series></ig:XFDataChart><ig:XFPieChart Grid.Row="1"ItemsSource="{Binding PiChartModels}"LabelMemberPath="Label"ValueMemberPath="Value"VerticalOptions="Center"/></Grid></ContentPage>

XFDataChartが今回折れ線グラフを表示していて、x軸に名前y軸に年齢を表示しています。XSPieChartが円グラフで性別の分布を表示しています。実行するとこんな感じになります。

f:id:okazuki:20160514150104p:plain

意外と簡単にチャートが出せますね。

UWPのItemsStackPanelで画面外に生成される項目の要素数を制御する

$
0
0

UWPのListViewって仮想化されますよね? そのとき画面から見えてない領域にどれくらいの要素を生成されるのかという話しですが、これはCacheLengthプロパティで制御できます。

デフォルトは4で、このとき上に表示領域の4個ぶん、下に表示領域の4個ぶん、表示領域も含めて合計9個ぶんの項目が生成されることになります。

ItemsStackPanel.CacheLength property - Windows app development

これを小さくすることで、起動時間とかを短縮できるらしいです。大きくすると、スクロールのパフォーマンスが向上するらしいです。色々試して微調整が必要そうですね。因みに設定の仕方は以下のような感じです。

<ListView ...>
    ...
    <ListView.ItemsPanel><ItemsPanelTemplate><ItemsStackPanel CacheLength="2"/></ItemsPanelTemplate></ListView.ItemsPanel>
    ...
</ListView>

UWPでgeneric.xamlを開く方法

$
0
0

基本的な色とかが定義されてるgeneric.xamlですが、こいつをたまに見たいことがあります。 そんなときどうするか?

プロジェクトを新規作成してMainPage.xamlApplicationPageBackgroundThemeBrushでF12を押します。

f:id:okazuki:20160516084458p:plain

そうするとgeneric.xamlをさくっと開けます。あとは見たい定義を見るだけ。

UWPでWindowのアクティブ状態を取りたい

$
0
0

ほしいときにぱっととる事はできなさそうです。

ということで、Window.Current.CoreWindowのActivatedイベントでとっておく必要があります。

こんな感じで

// どこかでイベントを購読して
Window.Current.CoreWindow.Activated += CoreWindow_Activated;

// こんな感じで状態をとっておくprivate CoreWindowActivationState State { get; set; }

privatevoid CoreWindow_Activated(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.WindowActivatedEventArgs args)
{
    // アクティブかどうかの状態をフィールドあたりにとっておくthis.State = args.WindowActivationState;
}

CoreWindowActivationState列挙体は、以下の値をもってます。

CoreWindowActivationState Enumeration (Windows)

  • CodeActivated: Activateによりアクティブ化された
  • Deactivated: 非アクティブ
  • PointerActivated: マウスやタッチでアクティブ化された

この値を見ることで、アクティブかどうかが判定できます。アクティブかどうかで見た目を変えるとかできそうですね。

HoloLensおさわり会の紹介

$
0
0

先日もBlogに書いた、Slikyfeelさんの開催しているHoloLensおさわり会ですが、日本各地で開催されてます。

直近は、今夜申し込み締め切りの岡山で開催のやつです。

hololens.connpass.com

そのほかに、名古屋、博多、愛媛・松山など、結構いろんなところで触れます。

hololens.connpass.com

HoloLensの感想

HoloLensですが、当たり前にホログラフィックが場所に固定されて出てくるのが、とてもすごいです。 ナチュラル過ぎて、凄さを忘れてしまうくらい凄いです。

例えば、部屋の壁にWindowを1つ貼り付けて置いておいたとします。 そして、色んなところに色んなオブジェクトを設置したり部屋をうろうろしたりして戻ってきても、ちゃんとそこにブレずにWindowが貼り付けられてる。 当たり前ですけど、凄いですよね?個人的にとても感動しました。

おさわり会ですが、私が参加した会と同じ感じなら、後半になればなるほど、色んな人が色んなものを置いてカオスになって楽しくなってきます。 行ける距離の範囲内で開催されてそうなら、是非一度参加してみて見るといいと思います。

未来をかぶれます。


Entity Framework Core RC2がリリースされたみたいです

$
0
0

blogs.msdn.microsoft.com

待ちに待ったリリースに向けてあと一歩といったところですね!

UWPで使うときに必要だったおまじないも消えてるっぽい(未確認だけどドキュメントに記載されてない)ので気軽にUWPで使えるようになったっぽいです。UWPでSQLiteを使うときの選択肢として期待大ですね。

うまくいかない…DataFactoryを使ってSQL Databaseの中身をData Lake Storeにコピーする

$
0
0

DataFactoryでコピーするだけなのにうまくいかない

何が足りてないんだろう要調査。誰か教えて。

やったこと

まず、East US2(DataLakeの置き場の都合)にData Lake StoreとSQL Databaseを作成します。

SQL Database側に以下のようなテーブルを定義しておきます。

CREATETABLE [dbo].[People]
(
    [Id] INT NOTNULL PRIMARY KEY
    , [Name] nvarchar(256) NOTNULL
)

そして、以下のようなデータを適当につっこんでおきます。

f:id:okazuki:20160518215602p:plain

Azure DataFactoryのVisual Studioプラグインを入れてVSからいじれるようにしておきます。

visualstudiogallery.msdn.microsoft.com

そうすると、プロジェクトの新規作成にDataFactoryが追加されるので、その中のEmpty Data Factory Projectを選択して作成します。

f:id:okazuki:20160518220154p:plain

LinkedServicesで追加の新規作成で先ほど作ったSQL Databaseへのリンクを作りましょう。「Azure SQL Linked Service」がそれっぽいです。

JSONが作られるのでサーバー名とかを先ほど作ったサーバーの名前に置き換えてJSONを完成させます。

{
    "$schema": "http://datafactories.schema.management.azure.com/schemas/2015-09-01/Microsoft.DataFactory.LinkedService.json",
    "name": "AzureSqlLinkedService1",
    "properties": {
        "type": "AzureSqlDatabase",
        "typeProperties": { 
            "connectionString": "Data Source=tcp:dfsampleserver.database.windows.net,1433;Initial Catalog=dfsample;User ID=okazuki@dfsampleserver;Password=*******;Integrated Security=False;Encrypt=True;Connect Timeout=30"
        }
    }
}

続けて保存先のData Lake Store(こちらもあらかじめ作っておきましょう)のLinkedServiceを作っておきます。「Azure Data Lake Store linked Service」がそれっぽいです。 こちらは、SQL Databaseのような硬派はJSONいじれよという感じじゃなくて、既存のData Lakeから選択させるようなUIが出ます。全部こうならいいのに。

f:id:okazuki:20160518220649p:plain

Nextを押すとData Factory Configurationに進むので、なんか作っておきましょう。

...

Visual Studioが異常終了しました。

ポータルでやろう

Visual Studioが何度やっても異常終了するのでポータルに戦場をうつします。

DataFactoryを新規作成します。名前はokazukidfにしました。リージョンはNorth Europeです。 okazukidfを選択して「Author and deploy」を選択します。

f:id:okazuki:20160518221704p:plain

New data storeを選択して生成されるJSONのservernameとかを埋めます。

{
    "name": "AzureSqlLinkedService",
    "properties": {
        "type": "AzureSqlDatabase",
        "description": "",
        "typeProperties": {
            "connectionString": "Data Source=tcp:dfsampleserver.database.windows.net,1433;Initial Catalog=dfsample;User ID=okazuki@dfsampleserver;Password=********;Integrated Security=False;Encrypt=True;Connect Timeout=30"
        }
    }
}

入力したらDeployを押します。

Data Lake Storeも追加して、画面上部にあるAuthrizeボタンを押して認証をさせます。

dataLakeStoreUriにadl://ではじまるURLをつっこんでDeployします。

{
    "name": "AzureDataLakeStoreLinkedService",
    "properties": {
        "type": "AzureDataLakeStore",
        "description": "",
        "typeProperties": {
            "authorization": "********",
            "dataLakeStoreUri": "adl://********.azuredatalakestore.net",
            "sessionId": "********"
        }
    }
}

次にNew datasetを選らんでDatasetを作ります。Azure SQLを選んで生成されたJSONをもとにぽちぽち頑張ります。

{
    "name": "AzureSQLDatasetTemplate",
    "properties": {
        "type": "AzureSqlTable",
        "linkedServiceName": "AzureSqlLinkedService",
        "structure": [],
        "typeProperties": {
            "tableName": "People"
        },
        "availability": {
            "frequency": "Minute",
            "interval": 15
        }
    }
}

linkedServiceNameに、先ほど作ったSQL DatabaseへのLinkedServiceの名前を入れるのがぽいんとです。

DataLake Storeも同じ要領で作ります。ここら辺から心が折れてきます。

{
    "name": "AzureDataLakeStoreDatasetTemplate",
    "properties": {
        "type": "AzureDataLakeStore",
        "linkedServiceName": "AzureDataLakeStoreLinkedService",
        "structure": [
            {
                "name": "ID,Name",
                "type": "int,string"
            }
        ],
        "typeProperties": {
            "folderPath": "/data/dfsample",
            "fileName": "People.csv",
            "format": {
                "type": "TextFormat"
            },
            "partitionedBy": [
                {
                    "name": "Year",
                    "value": {
                        "type": "DateTime",
                        "date": "SliceStart",
                        "format": "yyyy"
                    }
                },
                {
                    "name": "Month",
                    "value": {
                        "type": "DateTime",
                        "date": "SliceStart",
                        "format": "MM"
                    }
                },
                {
                    "name": "Day",
                    "value": {
                        "type": "DateTime",
                        "date": "SliceStart",
                        "format": "dd"
                    }
                },
                {
                    "name": "Hour",
                    "value": {
                        "type": "DateTime",
                        "date": "SliceStart",
                        "format": "HH"
                    }
                }
            ]
        },
        "availability": {
            "frequency": "Minute",
            "interval": 15
        }
    }
}

心が折れるにはまだ早い、New pipelineをクリックしていきます。startとendに適当な日付を入れたらAdd activityを選択しましょう。 Copy activityを選択します

適当にJSONを埋めます(心が折れた)

{
    "name": "PipelineTemplate",
    "properties": {
        "description": "description",
        "activities": [
            {
                "name": "CopyActivityTemplate",
                "type": "Copy",
                "inputs": [
                    {
                        "name": "AzureSQLDatasetTemplate"
                    }
                ],
                "outputs": [
                    {
                        "name": "AzureDataLakeStoreDatasetTemplate"
                    }
                ],
                "typeProperties": {
                    "source": {
                        "type": "SqlSource",
                        "sqlReaderQuery": "select * from People"
                    },
                    "sink": {
                        "type": "BlobSink"
                    }
                },
                "policy": {
                    "concurrency": 1,
                    "executionPriorityOrder": "OldestFirst",
                    "retry": 3,
                    "timeout": "01:00:00"
                },
                "scheduler": {
                    "frequency": "Minute",
                    "interval": 15
                }
            }
        ],
        "start": "2014-05-01T00:00:00Z",
        "end": "2019-05-05T00:00:00Z"
    }
}

これで放置しておいても、一向にデータがコピーされる気配がない。何が悪いんだろうか。

DIコンテナのUnityで使用されるコンストラクタを指定する

$
0
0

InjectionConstructorAttributeを使用します。指定しない場合はコンストラクタ引数の一番多いものが使われます。

例えば以下のようなケース。

publicclass Hoge
{
    public Hoge(Foo foo, Bar bar) { }
    public Hoge(Foo foo) { }
}

だと、Foo foo, Bar barのほうのコンストラクタが使われます。これをFoo fooのほうにしたかったら以下のようにします。

publicclass Hoge
{
    public Hoge(Foo foo, Bar bar) { }
    [InjectionConstructor]
    public Hoge(Foo foo) { }
}

ということで、良いUnityライフを。

UWPで一定間隔で表示が切り替わるPivotを作ろう

$
0
0

小ネタです。ViewModelあたりにSelectedIndexというプロパティをはやして、これを一定時間でインクリメントするようにします。 UIスレッド上でやるのがポイントですね。DispatcherTimerかRx使うのがいいでしょう。(RxのInterval使う場合はObserveOnでUIスレッドに持ってくる)

using Prism.Mvvm;
using System;
using System.Reactive.Linq;
using System.Threading;

namespace App37
{
    publicclass MainPageViewModel : BindableBase
    {
        privateint selectedIndex;

        publicint SelectedIndex
        {
            get { returnthis.selectedIndex; }
            set { this.SetProperty(refthis.selectedIndex, value); }
        }

        public MainPageViewModel()
        {
            Observable.Interval(TimeSpan.FromSeconds(5))
                .ObserveOn(SynchronizationContext.Current)
                .Subscribe(_ => this.ChangeSelectedIndex());
        }

        publicvoid ChangeSelectedIndex()
        {
            var current = this.SelectedIndex;
            current++;
            current = current >= 3 ? 0 : current;
            this.SelectedIndex = current;
        }
    }
}

今回はPivotが3画面あることを想定しているコードになります。XAML側は適当にPivotを用意して、PivotのSelectedIndexプロパティとTwoWayバインディングしてやります。

<Page
    x:Class="App37.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    xmlns:local="using:App37"    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"    mc:Ignorable="d">
    <Page.DataContext>
        <local:MainPageViewModel x:Name="ViewModel" />
    </Page.DataContext>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Pivot SelectedIndex="{x:Bind ViewModel.SelectedIndex, Mode=TwoWay}">
            <PivotItem Header="Item1">
                <TextBlock Text="Item1" />
            </PivotItem>
            <PivotItem Header="Item2">
                <TextBlock Text="Item2" />
            </PivotItem>
            <PivotItem Header="Item3">
                <TextBlock Text="Item3" />
            </PivotItem>
        </Pivot>
    </Grid>
</Page>

これで5秒間隔で表示の切り替わるPivotの完成です。

UWPでスクリーンショットを取らせないようにする

$
0
0

今日のde:codeのセッションで知ったことをメモしておきます。

UWPでは、以下のプロパティをfalseに設定することでスクリーンショットを取られることを抑止できます。 画面キャプチャされて、機密情報漏えいなくなりますね!

// これを入れる
ApplicationView.GetForCurrentView().IsScreenCaptureEnabled = false;

SnippingToolでキャプチャすると以下のようになりました。(黒い部分が画面)

f:id:okazuki:20160525003631p:plain

謎なところ

ボタンクリックに上記コードを書くとうまくいくのですが、PageのLoadedとかに書くとスプラッシュスクリーンから先に進まなくなります。この問題解決しないとちょっと使うの難しい…?

Viewing all 1388 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>