Daizen Ikehara

インフラジスティックス・ジャパン株式会社でデベロッパー エバンジェリストとして活動しています。
[Win] WinGrid – KeyActionMapping 一覧を表示 [Tips]

WinGrid をはじめとした Windows Forms コントロールではコンポーネントに対してあらかじめキーのマッピングが行われています。たとえば

  • Enter キーで確定
  • Escape キーで編集キャンセル

といったよくあるようなキー設定が行われています。

グリッド自体のキーマッピングは下記のヘルプドキュメントに記載されていますが、実際にコントロールから抜き出すことも可能です。

ヘルプ – WinGrid KeyActionMappings

今回のコードはこんな感じに

DataTable dt = new DataTable();

private void Form1_Load(object sender, EventArgs e)
{
            
    dt.Columns.Add("KeyCode");
    dt.Columns.Add("ActionCode");
    dt.Columns.Add("StateRequired");
    dt.Columns.Add("StateDisallowed");
    dt.Columns.Add("SpecialKeysRequired");
    dt.Columns.Add("SpecialKeysDisallowed");

    foreach (var action in this.ultraGrid1.KeyActionMappings)
    {
        dt.Rows.Add(new object[] { 
            action.KeyCode,
            action.ActionCode,
            action.StateRequired,
            action.StateDisallowed,
            action.SpecialKeysRequired,
            action.SpecialKeysDisallowed
        });
    }

    this.ultraGrid1.DataSource = dt;
    this.ultraGrid1.DataBind();
}

実行結果はこちら。

image

エクスポート可能なようにもしました。

サンプル プロジェクト

上記を実行させる場合はトライアル版が必要になります。

ダウンロード

[SharePoint] iOS 用の Office と SharePlus - 雑感

もうすでに様々なところで話題になっていますが、Microsoft さんが iPad 向けの Office (Word / Excel / PowerPoint) の公開や、Office Mobile for iPhone の無料提供を開始されました。

Office for iPad については日本国内への展開は今後ということですが、今回無料で使えるようになった Office Mobile for iPhone を試してみました。

AppStore – Microsoft Office Mobile

利用には Microsoft アカウントが必要ですが、OneDrive への接続も可能で個人利用を行う場合は十分なのではないでしょうか。

一方、ビジネス利用に関しては Office 365 サブスクリプションが必要とのことです。

    •Office 365 Small Business Premium
    •Office 365 Midsize Business
    •Office 365 Enterprise E3、E4 (エンタープライズおよび公共機関)
    •Office 365 Education A3、A4
    •Office 365 ProPlus

    MSDN サブスクリプションで提供されている Office 365 のアカウントを利用して SharePoint サイトのドキュメントの一覧を表示させてみました。

    もとのサイトはこちら

    image

     

    ドキュメント ライブラリはこちら

    image

    Office for iPhone で見てみると…

    20140402_055824000_iOS 20140402_055828000_iOS

    もちろん、Office ということで、閲覧と簡単な編集ができるようになっています。

    表示:

    20140402_061150000_iOS

    編集:

    20140402_061157000_iOS

    Office for iPad は iPad 専用というだけあってさらに完成度が高く、Microsoft さんの本気度を感じます。

    これで弊社の SharePlus のようなツールは不要… となってしまうわけにはいかないので、ここではエンタープライズ利用といった観点の機能を一つご紹介します。

    次の画像は Office for iPhone でのリスト一覧ですが、明らかにモバイル利用しないだろう、あるいはさせたくないようなフォルダまで表示されてしまいます。

     

    image

     

    SharePlus にはエンタープライズ利用を年頭においていくつかの管理機能を備えていますが、その一つに SharePlus 利用時における表示制御機能があります。SharePoint の権限ベースではなく、アプリケーション全体を通してモバイルでは利用させたくないサブサイトやリストをあらかじめ SharePoint 側のリストで定義することができます。

    これは MobileNavigation という名前のカスタムリストを利用して制御をおこないます。実際のリスト例はこちら

    image

     

    SharePlus はこのリストで指定されたリストのタイトルと Hidden フィールドの値に合わせて、表示・非表示を切り替えます。

    SharePlus で同じサイトのリスト一覧を表示させた場合はこちら。「アプリ パッケージ」や「スタイル ライブラリ」などモバイル利用では不要となったリストが非表示になり、そもそもアクセスもできなくなっています。

    20140402_055943000_iOS

    この MobileNavigation ではリスト単位でのオフライン利用の可否や、SharePlus でのアクセス時に利用されるデフォルトのビュー指定など、表示制御以外の項目を用意されています。

    簡単な例ですが、管理機能は企業導入の際に検討すべき項目です。SharePlus エンタープライズ版では様々な管理機能を提供しています。

    両方のアプリケーションの連携ということで、項目の一覧表示を SharePlus で行い、Office for iPhone / iPad で閲覧することも可能です。残念ながら編集機能の連携ができないため、閲覧のみにとどまってしまいますが、競合関係というよりはシーンに合わせて使い分けていくようになるのではないでしょうか。(個人的には編集機能の連携ができると弊社としてはうれしいのですが…)

     

    さて、この SharePlus ですが、近いうちにバージョンアップを予定しています。様々な新機能でさらなる価値を提供させていただく予定です。お楽しみに!

    2014 年 4 月期 Microsoft MVP 再受賞のご報告

    MVP_FullColor_ForScreen

    本年も昨年に引き続き Microsoft MVP を受賞させていただきました。

    Microsoft アワードプログラムとは

    昨年までは Client App Dev というカテゴリーでしたが、本年より Client Development MVP となり、さまざまなクライアント テクノロジに引き続き触れていきたいと考えています。

     

    今後ともよろしくお願いいたします。

     

    池原 大然
    デベロッパー エバンジェリスト
    インフラジスティックス・ジャパン(株)
    Microsoft MVP for Development Platforms – Client App Dev 2010/04 – 2014/03
    Microsofr MVP for Client Development 2014/04 – 2015/03

    [KnockoutJS] MVP Community Camp 2014 で登壇しました! [jQuery]

    2014 年 03 月 22 日に開催された MVP Community Camp 2014 において「Knockout.js を利用したインタラクティブ Web アプリケーション開発」というトピックでセッションに登壇させていただきました。

    当日のスライドはこちらで公開させていただきました。

    以前からいくつかのエントリでご紹介もしていますが、Knockout.js を利用することで、データの変更を UI に通知し、自動的に更新を行うことができます。弊社の jQuery 対応製品である、Ignite UI においてもいくつかのコントロールでサポートしています。

    Infragistics download

    似たようなトピックで 2014 年 04 月 05 日にわんくま同盟東京勉強会でも登壇させていただきます。こちらもよろしくお願いします。

    Knockout.js 関連エントリ

    [HTML] クライアント側データ コンポーネント – igDataSource [jQuery]

    2014 年 02 月 28 日に開催されたEnterprise × HTML5 Web Application Conference 2014 において「Web アプリケーションにおけるクライアントサイドのデータハンドリングと可視化の実現」というセッションを行わせていただきました。

    当日のセッション紹介させていただいた Ignite UI にはクライアント側でデータの操作を行う igDataSource が提供されています。このコンポーネントを利用するとクライアント側でソートやページングなどの処理が行えるようになります。

    まずはデータのロードからですが、単体のサンプルのため、ロード対象の JSON は予め読み込んでいます。もちろん igDataSource では Web サービスからロードさせることも可能です。

    JSON

    var customers = [{"CustomerID":"A1",
    	"CompanyName":"喫茶たいむましん",
    	"CompanyNameKana":"きっさたいむましん",
    	"ContactName":"林  千春"
    	,"ContactNameKana":"はやし ちはる",
    	"ContactTitle":"店長",
    	"Address":"佐賀市長瀬町 23-XX",
    	"City":"佐賀市",
    	"Region":null,
    	"PostalCode":"840-0853",
    	"Country":"佐賀県",
    	"Phone":"(0952)26-64XX",
    	"Fax":null},
    	 //省略

    ロードし、テンプレートに結果を流し込んだのちに HTML テーブルに出力させます。結果セットは igDataSource.dataView() メソッドで呼び出します。

    // テンプレート
    var template = "<tr>" +
        "<td>${CustomerID}</td><td>${CompanyName}</td>" +
        "<td>${ContactName}</td><td>${Country}</td>" +
        "<td>${City}</td><td>${Address}</td>" +
    "</tr>";
    
    ds = new $.ig.DataSource({
        type: "json",
        dataSource: customers,
        callback: function (success, error) {
            if (success) {
                // テンプレートに結果セットを流し込む。
                var rows = $.ig.tmpl(template, ds.dataView());
    
                $("#igTable").empty();
                $("#igTable").html(rows);
            }
            else {
                alert(error);
            }
        }
    });

    image

    今回、HTML テーブルを結果セット表示 UI として利用していますが、配列をデータソースとして取り扱う UI ウィジットであればどんなものにも利用することが可能です。

    次にこの情報をソートさせます。この場合は HTML テーブルへの働きかけを行うのではなく、データ コンポーネントに対してソート api を呼び出します。

    // 都道府県名、および 顧客番号をキーとしてソートする
    ds.sort([{ fieldName: "Country" }, { fieldName: "CustomerID" }], "asc", true);
    
    // 結果セットをテンプレートに流し込む
    var rows = $.ig.tmpl(template, ds.dataView());
    
    $("#igTable tbody").empty();
    $("#igTable").html(rows);

    ページングについても同様です。

        // ページング
        $("#igPagingEnable").click(function () {
    
            var myPagingSettings = {
                enabled: true,
                pageSize: 10,
                pageIndex: 0,
                type: "local"
            };
    
            // ページングを有効化
            ds.pagingSettings(myPagingSettings);
            ds.pageIndex(pageIndex);
    
            var rows = $.ig.tmpl(template, ds.dataView());
    
            $("#igTable tbody").empty();
            $("#igTable").html(rows);
        });
    
        $("#next").click(function () {
    
            // 次のページ分のデータを読み込む。
            ds.nextPage();
            var rows = $.ig.tmpl(template, ds.dataView());
    
            $("#igTable tbody").empty();
            $("#igTable").html(rows);
        });
    
        $("#prev").click(function () {
                    
            // 前のページ分のデータを読み込む。
            ds.prevPage();
            var rows = $.ig.tmpl(template, ds.dataView());
                   
            $("#igTable tbody").empty();
            $("#igTable").html(rows);
        });
    });

    実行結果はこちら

     

    サンプル

    Ignite UI のダウンロードはこちら

    トライアル版はこちらよりダウンロードいただけます。

    download-button

    Ignite UI 2013 Volume2 新機能エントリ

    Knockout.js 関連エントリ

    [XAML] xamDataChart - Marker のデータ コンテキスト その2 [Tips]

    前回は XamDataChart のマーカーをカスタマイズする際に有用なオブジェクトをご紹介しましたが、今回は更に一歩進んで下記の要件を満たします。

    • 特定のデータ点のみマーカーを表示したい。

    上記の用件を満たす実装例としてはチャートにバインドするデータにこの表示、非表示を制御するプロパティを追加し、その情報をマーカー側で取得するというものになります。

    チャートにバインドされるデータ点のクラス

    public class ChartData : INotifyPropertyChanged
    {
        private string label;
        public string Label
        {
            get { return this.label; }
            set
            {
                if (this.label != value)
                {
                    this.label = value;
                    NotifyPropertyChanged();
                }
            }
        }
    
        private int value;
        public int Value
        {
            get { return this.value; }
            set
            {
                if (this.value != value)
                {
                    this.value = value;
                    NotifyPropertyChanged();
                }
            }
        }
    
        // データポイントマーカーの表示・非表示状態を保持
        private bool isVisible;
        public bool IsVisible
        {
            get { return isVisible; }
            set
            {
                if (this.isVisible != value)
                {
                    this.isVisible = value;
                    NotifyPropertyChanged();
                }
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    }

    そして、サンプルデータクラスでは、閾値を保存しておきます。

    public class ChartSampleData : List<ChartData>, INotifyPropertyChanged
    {
        // 基準値
        private int threshold;
        public int Threshold
        {
            get { return threshold; }
            set
            {
                if (this.threshold != value)
                {
                    this.threshold = value;
                    NotifyPropertyChanged();
                }
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
    
        public ChartSampleData() { }
    
        public ChartSampleData(bool isGeneratingSample)
        {
            if (isGeneratingSample)
            {
                Random rand = new Random(DateTime.Now.Millisecond);
    
                // 基準値を設定
                this.Threshold = rand.Next(30);
    
                // チャート項目の初期化
                this.AddRange(Enumerable.Range(1, 20)
                    .Select(i => new ChartData
                    {
                        Label = i.ToString(),
                        Value = rand.Next(30),
                        IsVisible = true
                    }));
    
                // しきい値の判定
                this.Where(p => p.Value < this.Threshold)
                    .ToList().ForEach(i => i.IsVisible = false);
            }
        }
    }

    次に XAML 側ですが、前回のマーカーテンプレートで使用していた Grid の Visiblity プロパティに先ほどの IsVisible をバインドさせます。また、フレームワークから提供されている BooleanToVisibilityConverter を利用します。

    <ig:LineSeries.MarkerTemplate>
        <DataTemplate>
            <!-- マーカーの表示非表示を制御 -->
            <Grid Visibility="{Binding Path=Item.IsVisible, Converter={StaticResource BooleanToVisibilityConverter}}">
                <Ellipse Width="20" Fill="LightBlue" Height="20"></Ellipse>
                <!-- こちらに固有のマーカーを設定 -->
                <TextBlock HorizontalAlignment="Center" 
                            VerticalAlignment="Center"
                            Text="{Binding Path=Item.Value}" />
            </Grid>
        </DataTemplate>
    </ig:LineSeries.MarkerTemplate>

    ここまでの実行結果

    image

    閾値(この場合は 15)よりも小さいデータ点についてはマーカーそのものの表示を行いません。

     

    さて、今のままでは閾値が数値で表示されているだけなのでわかり辛い表現になってしまします。そこで、基準線を表現できる、ValueOverlay を使用します。

    <ig:ValueOverlay Axis="{Binding ElementName=axisY}"
                    Value="{Binding Path=Threshold}"
                    Thickness="5"
                    Brush="Red"
                    DashArray="1" />

    実行結果を見るとよりわかりやすくなっています。

    image

    完全な XAML

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:sys="clr-namespace:System;assembly=mscorlib"
            xmlns:local="clr-namespace:XamDataChart_MarkerTemplate"
            xmlns:ig="http://schemas.infragistics.com/xaml"
            x:Class="XamDataChart_MarkerTemplate.MainWindow"
            Title="MainWindow" Height="350" Width="525">
        <Window.Resources>
            <BooleanToVisibilityConverter 
                x:Key="BooleanToVisibilityConverter"/>
            <ObjectDataProvider x:Key="ChartData" 
                                ObjectType="{x:Type local:ChartSampleData}">
                <ObjectDataProvider.ConstructorParameters>
                    <sys:Boolean>True</sys:Boolean>
                </ObjectDataProvider.ConstructorParameters>
            </ObjectDataProvider>
        </Window.Resources>
        <Grid DataContext="{Binding Source={StaticResource ChartData}}">
            <Grid.RowDefinitions>
                <RowDefinition Height="30"/>
                <RowDefinition />
            </Grid.RowDefinitions>
            <ig:XamDataChart  Grid.Row="1">
                <ig:XamDataChart.Axes>
                    <ig:CategoryXAxis 
                                      x:Name="axisX" ItemsSource="{Binding}"
                                      Label="{}{Label}" />
                    <ig:NumericYAxis x:Name="axisY" />
                </ig:XamDataChart.Axes>
                <ig:XamDataChart.Series>
                    
                    <ig:LineSeries 
                                    Title="出荷数量"
                                    ItemsSource="{Binding}"
                                    ValueMemberPath="Value"
                                    XAxis="{Binding ElementName=axisX}"
                                    YAxis="{Binding ElementName=axisY}" 
                                    >
                        <ig:LineSeries.MarkerTemplate>
                            <DataTemplate>
                                <!-- マーカーの表示非表示を制御 -->
                                <Grid Visibility="{Binding Path=Item.IsVisible, 
            Converter={StaticResource BooleanToVisibilityConverter}}">
                                    <Ellipse Width="20" Fill="LightBlue" Height="20" />
                                     <!-- こちらに固有のマーカーを設定 -->
                                    <TextBlock HorizontalAlignment="Center" 
                                                VerticalAlignment="Center"
                                                Text="{Binding Path=Item.Value}" />
                                </Grid>
                            </DataTemplate>
                        </ig:LineSeries.MarkerTemplate>
                    </ig:LineSeries>
                    <!-- オーバーレイ -->
                    <ig:ValueOverlay Axis="{Binding ElementName=axisY}"
                                Value="{Binding Path=Threshold}"
                                Thickness="5"
                                Brush="Red"
                                DashArray="1" />
                </ig:XamDataChart.Series>
            </ig:XamDataChart>
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="閾値:" VerticalAlignment="Center" />
                <TextBlock Text="{Binding Path=Threshold}" 
    			VerticalAlignment="Center"  />
            </StackPanel>
        </Grid>
    </Window>

    さらにこの閾値を実行時に変更し情報を反映させることも可能です。詳細は下記のサンプル ソリューションを参照してください。

    サンプル ソリューション

    上記サンプルを動作させる場合は Infragistics Ultimate トライアル版をダウンロードいただき、Infragistics WPF をインストールいただく必要があります。

    download-button

    関連エントリ

    [XAML] xamDataChart - Marker のデータ コンテキスト [Tips]

    xamDataChart ではデータ点を強調表示するマーカー機能が存在しています。

    image

    オンラインヘルプ - マーカー

    このマーカーは上記のように円形のものや長方形、五角形、ダイアモンド型、三角形など様々な種類が用意されているのに加えて、Series 内において、MarkerTemplate を利用することでカスタマイズが可能になっています。

    <ig:XamDataChart DataContext="{Binding Source={StaticResource ChartData}}" Grid.Row="1">
        <ig:XamDataChart.Axes>
            <ig:CategoryXAxis x:Name="axisX" ItemsSource="{Binding}"
                                Label="{}{Label}" />
            <ig:NumericYAxis x:Name="axisY" />
        </ig:XamDataChart.Axes>
        <ig:XamDataChart.Series>
            <ig:LineSeries
                            Title="出荷数量" 
                            ItemsSource="{Binding}"
                            ValueMemberPath="Value"
                            XAxis="{Binding ElementName=axisX}"
                            YAxis="{Binding ElementName=axisY}" 
                            >
                <ig:LineSeries.MarkerTemplate>
                    <DataTemplate>
                        <!-- こちらに固有のマーカーを設定 -->
                        <TextBlock Text="まーかー" />
                    </DataTemplate>
                </ig:LineSeries.MarkerTemplate>
            </ig:LineSeries>
                  
        </ig:XamDataChart.Series>
    </ig:XamDataChart>

    image

    更にこの MarkerTemplate の各項目の DataContext には現在のシリーズの情報や、ラベル名、値などを取得できるオブジェクトが割り当てられます。

    今回は Snoop を利用して確認してみましょう。

    image

    Marker オブジェクトの Content プロパティにはインフラジスティックス独自の DataContext クラスが割り当てられており、先ほどの DataTemplate の DataContext にこの Content プロパティの内容が割り当てられていることが確認できます。

    Infragistics.Controls.Charts.DataContext

    この Infragistics.Controls.Charts.DataContext クラスでは下記のプロパティを公開しています。

    プロパティ名 説明
    Item 現在のチャート点に割り当てられている DataContext の値
    Series このマーカーを表示するチャート点のシリーズ オブジェクト

    これらの値にアクセスすることができるのでかなり自由な表現を行うことができます。

    例えば上記のチャートはチャートの値をバインドされているクラスの Value 値に設定しているため、下記のように設定することで個々のチャート点において値を表示させることができます。

    <ig:XamDataChart DataContext="{Binding Source={StaticResource ChartData}}" Grid.Row="1">
        <ig:XamDataChart.Axes>
            <ig:CategoryXAxis x:Name="axisX" ItemsSource="{Binding}"
                                Label="{}{Label}" />
            <ig:NumericYAxis x:Name="axisY" />
        </ig:XamDataChart.Axes>
        <ig:XamDataChart.Series>
            <ig:LineSeries 
                            Title="出荷数量"
                            ItemsSource="{Binding}"
                            ValueMemberPath="Value"
                            XAxis="{Binding ElementName=axisX}"
                            YAxis="{Binding ElementName=axisY}" 
                            >
                <ig:LineSeries.MarkerTemplate>
                    <DataTemplate>
                        <!-- こちらに固有のマーカーを設定 -->
                        <Grid>
                            <Ellipse Width="20" Fill="LightBlue" Height="20"></Ellipse>
                            <TextBlock HorizontalAlignment="Center" 
                                        VerticalAlignment="Center"
                                        Text="{Binding Path=Item.Value}" />
                        </Grid>
                    </DataTemplate>
                </ig:LineSeries.MarkerTemplate>
            </ig:LineSeries>
                  
        </ig:XamDataChart.Series>
    </ig:XamDataChart>

    image

    ここまで来ると次に

    • 特定のデータ点のみマーカーを表示したい。
    • 特定のマーカーの色を変更したい。

    というような要望が出てくるかもしれません。基本的な考え方は同じですが次回以降に実装例をご紹介できればと思います。

    サンプル ソリューション

    上記サンプルを動作させる場合は Infragistics Ultimate トライアル版をダウンロードいただき、Infragistics WPF をインストールいただく必要があります。

    download-button

    [WPF] XamQRCodeBarcode の情報を Report に渡す [Tips]

    前回のエントリで WPF アプリケーションで表示しているビジュアル要素を保存する方法を紹介させていただきましたが、実はアプリケーションから画像情報を Infragistics Reporting に渡すことが要件でした。

    そこで今回は Infragistics Reporting のデータソースとしてオブジェクト データソースを利用しながら実行時にレポートデータを渡していきます。

    アプリケーションの UI このような感じに変更されています。

    image

    印刷ボタンを押下すると参加証のプレビューを表示するという内容です。

    オブジェクトデータソースを利用したレポートの作成はこちら

    ヘルプ – オブジェクト データ ソースへレポートをバインド

    上記の内容に基づいて下記のクラスをそれぞれ作成しました。

    Registrant.cs

    /// <summary>
    /// イベント登録者の情報
    /// </summary>
    public class Registrant
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public byte[] QRCodeImage { get; set; }
    }

    EventRegistration.cs

    public class EventRegistration : List<Registrant>
    {
        public EventRegistration()
        {
        }
        public IEnumerable<Registrant> GetRegistrants()
        { 
            return this;
        }
    }

    レポートはこちら。青枠の部分にイメージデータを渡します。

    image

    image

     

    次に実行時にアプリケーション側からデータを渡す準備を行います。ボタンクリックのイベントハンドラーで上記の EventRegistration クラスのインスタンスを作成します。

    MainWindow.xaml.cs

    private void Button_Click(object sender, RoutedEventArgs e)
    {
    
        // DPI を 96 として呼び出す。
        var bitmapSource = CaptureScreen(this.xamQRCode, 96, 96);
    
        // PNG 形式へのエンコーディング
        var enc = new PngBitmapEncoder();
        enc.Frames.Add(BitmapFrame.Create(bitmapSource));
    
        // レポート用のデータ作成
        EventRegistration er = new EventRegistration();
        using (MemoryStream ms = new MemoryStream())
        {       
            enc.Save(ms);
            // 参加者を登録。QR コードの画像情報も渡す。
            er.Add(new Registrant { 
                ID = 1,
                Name = this.tb1.Text,
                QRCodeImage = ms.ToArray()
            });
        }
    
        // レポートウィンドウを作成し DataContext に EventRegistration を渡す。
        ReportWindow win = new ReportWindow();
        win.DataContext = er;
        win.ShowDialog();
    }

    上記コードの最後で作成した EventRegistration クラスのインスタンスを ReportWindow.DataContext へと渡しています。

    レポートを表示させる ReportWindow には XamReportViewer コントロールを配置し、ClientRenderSettings 内でアプリケーションからレポートデータを渡すように設定しています。

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:ig="http://schemas.infragistics.com/xaml" 
    		x:Class="QRCodeApp.ReportWindow"
            Title="ReportWindow" WindowState="Maximized" Height="300" Width="300">
        <Grid>
            <ig:XamReportViewer x:Name="xrv">
                <ig:XamReportViewer.RenderSettings>
                    <ig:ClientRenderSettings 
                        DefinitionUri="/QRCodeApp;component/Reporting/Report1.igr">
                        <!-- レポートデータを実行時に渡す -->
                        <ig:ClientRenderSettings.DataSources>
                            <ig:DataSource TargetDataSource="Registrant"
                                             ItemsSource="{Binding}" />
                        </ig:ClientRenderSettings.DataSources>
                    </ig:ClientRenderSettings>
                </ig:XamReportViewer.RenderSettings>
            </ig:XamReportViewer>
    
        </Grid>
    </Window>

    実行結果はこちら。アプリケーションで入力した内容をもとにレポートを作成することができます。
    インフラジスティックス Developer Days、ご無沙汰なのでやりたいですね!

    image

    サンプル プロジェクト

    上記サンプルを動作させる場合は Infragistics Ultimate トライアル版をダウンロードいただき、Infragistics WPF / Infragistics Reporting をインストールいただく必要があります。

    download-button

    関連情報

    [WPF] XamQRCodeBarcode を画像として保存 [Tips]

    ひさびさに WPF のお話です。

    とある件で画面に描画している Visual 要素を画像として取り扱う必要がでました。以前からよく知られている方法ですが、WPF では次の 2 つのクラスを利用することで実現可能となります。

    アプリケーションに表示された Visual に対して利用すると親レイアウトからのオフセットを無視した描画になってしまうのですが、MSDN Blog に回避方法が記載されています。(2009 年と少し古い記事ですが)

    MSDN Blog - Jaime Rodriguez: RenderTargetBitmap tips

    今回のサンプルは XamQRCodeBarcode コントロールを配置し、TextBox の値と QR コードの値をデータバインディングで連結しています。

    image

    保存ボタンを押すと QR コードの画像を保存するようにします。

    using Microsoft.Win32;
    using System;
    using System.IO;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    
    namespace QRCodeApp
    {
        /// <summary>
        /// MainWindow.xaml の相互作用ロジック
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                // DPI を 96 として呼び出す。
                var bitmapSource = CaptureScreen(this.xamQRCode, 96, 96);
                
                // PNG 形式へのエンコーディング
                var enc = new PngBitmapEncoder();
                enc.Frames.Add(BitmapFrame.Create(bitmapSource));
    
                SaveFileDialog diag = new SaveFileDialog();
                diag.DefaultExt = ".png";
                diag.Filter = "PNG (*.png) | *.png";
                diag.InitialDirectory = 
                    Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                if (diag.ShowDialog(this).GetValueOrDefault())
                {
                    using (Stream fs = diag.OpenFile())
                    {
                        enc.Save(fs);
                    }
                }
            }
    
            // サンプルコード出典:
            // http://blogs.msdn.com/b/jaimer/archive/2009/07/03/rendertargetbitmap-tips.aspx
            private static BitmapSource CaptureScreen(Visual target, 
    		double dpiX, double dpiY)
            {
                if (target == null)
                {
                    return null;
                }
                Rect bounds = VisualTreeHelper.GetDescendantBounds(target);
                RenderTargetBitmap rtb = new RenderTargetBitmap(
                    (int)(bounds.Width * dpiX / 96.0),
                    (int)(bounds.Height * dpiY / 96.0),
                    dpiX,
                    dpiY,
                    PixelFormats.Pbgra32);
                
                DrawingVisual dv = new DrawingVisual();
                using (DrawingContext ctx = dv.RenderOpen())
                {
                    VisualBrush vb = new VisualBrush(target);
                    ctx.DrawRectangle(vb, null, new Rect(new Point(), bounds.Size));
                }
                rtb.Render(dv);
                return rtb;
            }
        }
    }

    このデータをどう利用したかったのかは…次回に続きます。

    サンプル ソリューション

    サンプルを動作させる場合は下記のボタンから Infragistics WPF コントロールをダウンロードし、インストールを行ってください。

    download-button

    関連情報

    [WPF] テスト自動化 Friendly [Win]

    昨年の Developers Summit 関西 2013 にお邪魔させていただいた際に、株式会社 Codeer の石川さんよりテスト自動化のためのライブラリ、Friendly をご紹介いただきました。

    先日 2.0 がリリースされ NuGet からも取得できるとご連絡をいただきました。会社さんのお名前で検索するとでてきますね。

    image

    詳細はこちらをご覧いただければと思いますが、プロダクトプロセスを、「プログラムレベル」で、テストプロセスから操作できるという点が特長とのこと。

    Infragistics WPF コントロールを利用したサンプルも同時にご提供いただきました。

    テストサンプル

    サンプルを動作させるためには Infragistics WPF コントロールのトライアル版が必要になります。

    download-button

    また、7 以降の PC では zip 解凍前にブロックを解除する必要があります。

    image

    テストを実行するとこんな感じにテストプロセスからテスト対象の XamGrid のセルの値を操作しています。

    image

    Windows Forms, WPF プロジェクトにおいてのテストにご興味があれば是非チェックしてみてください。

    [HTML5] Ignite UI と Knockout.js その 1– igEditors [jQuery]

    順序が逆になってしまいましたが、Ignite UI 2013 Volume 2Knockout.js をサポートしているコントロール・機能をまとめました。

    このバージョンにおいて Knockout.js へのインテグレーションを行っているコントロールは下記の通りとなります。

    • igCombo
    • igDataChart
    • igEditors
    • igGrid
    • igHierarchicalGrid
    • igTree

    上記のコントロールでは Knockout.js サポートのための拡張が行われており、ビジネスデータと UI を分離させることができるようになっています。

    今回は前回作成したチャートのサンプルにエディターを組み合わせ、そのエディターではチャートに表示するデータ点数を表示させます。この値はユーザーが変更可能とします。

     

    ViewModel:

    ViewModel に最大表示数を保持する maxNumber プロパティを実装します。

    function CreateViewModel() {
        var self = this;
    
        // 省略
    
        // チャートで表示させるデータの総数
        self.maxNumber = ko.observable(10);
    }

     

    Infragistics Loader:

    更に Infragistics Loader では Resource としてエディター用の igEditors、Knockout.js サポート拡張である、infragistics.ui.editors.knockout-extensions.js を読み込むようにします。

    $(function () {
        // Infragistics Loader の利用、ここでknockout-extensions をロード
        $.ig.loader({
            scriptPath:
                "http://cdn-na.infragistics.com/jquery/20132/latest/js/",
            cssPath:
                "http://cdn-na.infragistics.com/jquery/20132/latest/css/",
            resources:
                "igDataChart.*,extensions/infragistics.ui.datachart.knockout-extensions.js,igEditors,igEditors,extensions/infragistics.ui.editors.knockout-extensions.js",
            ready: function () {
                // ViewModel の初期化とバインディング設定
                viewModel = new CreateViewModel();
                ko.applyBindings(viewModel);
            }
        });
    
    });

     

    HTML:

    input タグに data-bind を設定します。

    <input id="maxNumberInput" data-bind="igNumericEditor: { value: maxNumber}" />

    今回は問題ありませんが、エディター コントロールを利用する際にベースとなる要素を input とした場合は動作に制限がありますので、こちらも確認してください。

    本題はここまでですが、今回のサンプルではデータの追加時に最大数を超えないように変更を加えました。

    また、igNumericEditor はデフォルトてマイナス値も入力として受け付けてしまうため、こちらもプロパティを設定し 0 – 30 の間とします。

    実行結果はこちら

     

     

    Knockout.js を利用することでよりインタラクティブな UI を少ないコード量で構築することができました。

    サンプルソース

     

    トライアル版はこちらよりダウンロードいただけます。

    download-button

    Ignite UI 2013 Volume2 新機能エントリ

    Knockout.js 関連エントリ

    [HTML5] igDataChart と Knockout.js その 2 - データの更新 [jQuery]

    前回は Knockout.js を利用してチャートにデータを表示させることに成功しました。Knockout.js を利用する最大の利点は、データの更新が行われた場合、追加のコードを必要とせず、チャートが更新されるという点にあります。

    前回のサンプルに 2 つボタンを追加し、それぞれチャートデータを更新開始、停止するコードを下記のように追加しました。

     

    ViewModel:

    CreateViewModel 内に feedTimer 変数、そして開始と終了を制御するメソッドを追加します。

    // ViewModel 作成メソッド
    function CreateViewModel() {
        var self = this;
        // チャートデータを作成..省略
        self.data = ko.observableArray(
                    [{
                        label: ko.observable("1"),
                        value1: ko.observable(100 * Math.random()),
                    },
                    {
                        label: ko.observable("2"),
                        value1: ko.observable(100 * Math.random()),
                    },
                    {
                        label: ko.observable("3"),
                        value1: ko.observable(100 * Math.random()),
                    },
                    {
                        label: ko.observable("4"),
                        value1: ko.observable(100 * Math.random()),
                    },
                    {
                        label: ko.observable("5"),
                        value1: ko.observable(100 * Math.random()),
                    }]
            );
    
        // タイマー
        self.feedTimer = ko.observable(null);
    
        // データの追加を開始
        self.startFeedingData = function () {
                self.feedTimer(setInterval(
                function () {
                    self.data.push
                    ({
                        label: ko.observable(self.data().length + 1),
                        value1: ko.observable(100 * Math.random())
                    });
                }, 300));
        };
    
        // データの追加を停止
        self.stopFeedingData = function () {
                clearInterval(self.feedTimer());
                self.feedTimer(null);
        };
    }

    HTML:

    ボタン エレメントを追加し、それぞれに click binding を利用し startFeedingData, stopFeedingData をバインディングします。

    <button id="Start" data-bind="click: startFeedingData">開始</button>
    <button id="End" data-bind="click: stopFeedingData">停止</button>

    ここまでの実行結果

     

    ただし、この実装では開始、停止ボタンのクリックアクションを多重で起動できるため、別途 enable binding, disable binding を設定しました。

    <button id="Start" 
    	data-bind="click: startFeedingData, enable: feedTimer() === null">開始</button>
    <button id="End" 
    	data-bind="click: stopFeedingData, disable: feedTimer() === null">停止</button>

    こうすることで、ボタンの活性、不活性を制御することができるようになります。

    サンプルソース

     

    トライアル版はこちらよりダウンロードいただけます。

    download-button

    Ignite UI 2013 Volume2 新機能エントリ

    [HTML5] igDataChart と Knockout.js その 1 - データの表示 [jQuery]

    HTML/jQuery コントロール ライブラリーである、Ignite UI では様々な JavaScript ライブラリーとのインテグレーションをサポートしていますが、この 2013 Volume 2 では Knockout.js のサポートを拡充しました。

    Knockout.js とは?

    Knockout.js サイト

    Knockout.js はリッチな、そしてレスポンシブな表示や編集 UI をデータモデルへの参照をベースとして実現します。XAML の世界では Model View View Model パターンとしてよく知られているデザイン パターンを JavaScript の世界に持ち込んだと考えることができます。

    主要機能

    • 依存関係のトラッキング – データ モデルの変更に合わせて UI が自動的に更新される
    • 宣言的なバインディング – UI とデータ モデルを容易に結びつけることができる
    • 優れた機能拡張性 – カスタム ビヘイビアーの実装も可能

    Ignite UI グリッド コントロールである、igGrid は以前からこの Knockout.js をサポートしていましたが、2013 Volume 2 リリースからは HTML5 チャートである igDataChart もサポートを開始しました。この結果、チャートデータの更新を Chart API を利用せずとも UI に即時反映することができるようになります。

    今回は初回ということでデータを表示させるまでをご紹介します。

     

    1. 必要なリソースの設定

    jQuery, jQuery UI, Knockout.js および Ignite UI のリソースは全て CDN 経由で取得することができるので、今回はそちらを利用します。

    <head>
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"
        type="text/javascript"></script>
      <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.21/jquery-ui.min.js" 
        type="text/javascript"></script>
      <script src="http://cdnjs.cloudflare.com/ajax/libs/knockout/2.3.0/knockout-min.js" 
        type="text/javascript"></script>
      <!-- Infragistics Loader  -->
      <script src="http://cdn-na.infragistics.com/jquery/20132/latest/js/infragistics.loader.js"
         type="text/javascript"></script>
    </head>

     

    2. ViewModel の設定

    ViewModel の作成メソッドを下記のように作成し、data プロパティに observableArray を設定しました。こうすることでこの配列へのデータ追加を行ったり、削除を行った場合に変更が通知されるようになります。

    <script type="text/javascript">
        // ViewModel
        var viewModel;
    
        // ViewModel 作成メソッド
        function CreateViewModel() {
            var self = this;
            // チャートデータを作成
            this.data = ko.observableArray(
                        [{
                            label: ko.observable("1"),
                            value1: ko.observable(100 * Math.random()),
                        },
                        {
                            label: ko.observable("2"),
                            value1: ko.observable(100 * Math.random()),
                        },
                        {
                            label: ko.observable("3"),
                            value1: ko.observable(100 * Math.random()),
                        },
                        {
                            label: ko.observable("4"),
                            value1: ko.observable(100 * Math.random()),
                        },
                        {
                            label: ko.observable("5"),
                            value1: ko.observable(100 * Math.random()),
                        }]
                );
        }
    </script>

     

    4. Infragistics Loader を利用したリソースの読み込みとバインディング

    つぎにドキュメント ロード時に Infragistics Loader の初期化および ViewModel のインスタンスを作成します。その後、バインディングの設定を行います。

    Infragistics Loader の resources では、igDataChart 関連および、Knockout.js をサポートするためのリソースを指定しています。

    <script type="text/javascript">
    
        $(function () {
            // Infragistics Loader の利用、ここでknockout-extensions をロード
            $.ig.loader({
                scriptPath: 
    	"http://cdn-na.infragistics.com/jquery/20132/latest/js/",
                cssPath: 
    	"http://cdn-na.infragistics.com/jquery/20132/latest/css/",
                resources: 
    	"igDataChart.*,extensions/infragistics.ui.datachart.knockout-extensions.js",
                ready: function () {
                    // ViewModel の初期化とバインディング設定
                    viewModel = new CreateViewModel();
                    ko.applyBindings(viewModel);
                }
            });
        });
    
    </script>

     

    3. バインディング

    最後に HTML 要素において data-bind 属性を指定しその内部で igDataChart を呼び出します。

    こうすることにより、HTML 要素とデータがバインディングされます。

    <div id="chart" data-bind='igDataChart: {
        title: "とあるチャート",
        titleTextStyle: "20pt Bold Meiryo",
        dataSource: data,
        width: "1024px",
        axes: [{
            name: "xAxis",
            type: "categoryX",
            label: "label",
        }, {
            name: "yAxis",
            type: "numericY",
        }],
        series: [{
            name: "splineSeries1",
            type: "spline",
            markerType: "automatic",
            xAxis: "xAxis",
            yAxis: "yAxis",
            valueMemberPath: "value1"
        }] }'></div>

     

    image

    今回はチャートにデータを表示するところまででしたが、次回からはいよいよデータモデルの更新を行います。

     

    トライアル版はこちらよりダウンロードいただけます。

    download-button

     

    Ignite UI 2013 Volume2 新機能エントリ

    [13.2] Ignite UI: jQuery, HTML5, ASP.NET MVC - 新機能 その4

    長かった新機能シリーズも今回が最終回です。この後はまた様々な技術情報をお伝えしていきます。

    原文(参考元)– Jason Beres: Ignite UI: What’s New in jQuery, HTML5 & ASP.NET MVC in 13.2

     

    グリッド

    • 列固定 – 2013 Volume 1 では CTP であった列固定機能が正式版としてサポート開始です。弊社グリッド コントロールの定番機能ですね。さらに下記の機能と同時に利用することができるようになっています。

     

    その他の主な追加機能はこちら。

    • 複数列ヘッダー機能
    • 集計機能
    • 列リサイズ機能
    • 更新
    • 列幅のパーセンテージ指定
    • 日付のフィルタリング
    • セルマージ機能
    • 機能セレクター
    • 行セレクター
    • ロードオンデマンドのスクロールサポート CTP – ロードオンデマンドを利用した際にエンドユーザーがスクロールを行った際あるいは、[更に読み込む] といったようなボタンをクリックしたアクションで読み込むように選択できるようになりました。

    • jsRender インテグレーション – 有名なオープン ソースライブラリーである、jsRender を利用したグリッド内部のテンプレート(例:セルテンプレート)をサポートしました。

    • レスポンシブ デザイン 垂直レンダリング – レスポンシブ モードでグリッドを利用した際に、画面サイズに合わせて自動的に 1 レコードを複数行で表示できるようになりました。

    • igGrid / igHieracrhicalGrid 機能セレクター - 機能セレクターが下記のようにタッチインタラクションに対応できるよう再デザインされました。こちらの方が使いやすそうです。

     

    ブラウザー履歴とのインテグレーション

    単一ページ アプリケーションにおいてブラウザーの履歴を管理できることは非常に重要となりますが、Ignite UI コントロールの API を利用することで、history.js のような履歴管理を行うライブラリー利用をサポートすることが可能になりました。

    • イベント時の引数を充実させ、履歴管理に必要な情報を取得

    • 現在の状態のシリアライズ
    • API を利用した状態復帰(例: テキストを以前のものに差し替える.. など)

    • Ignite UI 全体を通した共通のデザイン原則により、より良いアプリケーション デザイン、コードの構造の実現

       

    地理情報マップ

    高密度散布シリーズ - geographicHighDensityScatterSeries を利用することで何百万点もの高密度データをマップに投影することが可能になります。

     

    新しいサンプル

    このリリースではサンプルブラウザーを 1 から再作成し、よりよりユーザー体験をもたらすように向上させました。必要なスクリプトファイルの入手やサンプルコードの試行を簡単に行えるようになっています。ぜひ、こちらをご覧ください。http://jp.iguiteui.com

    image 

    ぜひ、お試しください!

    download-button

    2013 Volume2 新機能エントリ

    [13.2] Ignite UI: jQuery, HTML5, ASP.NET MVC - 新機能 その3

    Ignite UI 2013 Volume 2 にはまだまだ多くの新機能が追加されています。今回もいくつかご紹介します。

    原文(参考元)– Jason Beres: Ignite UI: What’s New in jQuery, HTML5 & ASP.NET MVC in 13.2

     

    データ チャート

    以前から提供してきた Ignite UI jQuery データ チャート コントロールは非常に高機能なチャートに仕上がっていました。この 2013 Volume 2 リリースでは Web & ハイブリッド アプリケーション開発者にとって有用となる新しいルック & フィールやグラデーション配色のサポート、新しい範囲セレクター、Knockout.js のサポートなどが追加されています。また、エンドユーザーがマウスやタッチ ジェスチャーでチャートの拡大を行ったり、要素の指定を行えたりと新しいインタラクション機能が提供されています。

    主要機能

    • 新しいルック & フィール – すでに 40 種類以上のチャート タイプが提供されていることに加え大量データを素早く処理できるパフォーマンスを備えていますが、このリリースではチャートの外観を向上させる様々な要素が追加され、定義できるようになりました。
       

      • チャートのタイトル – チャートのタイトルならびに副タイトルが設定できるようになりました。またこれらの値が設定された場合は自動的にチャートのデータ領域のリサイズが行われます。

         

      • 軸のタイトル – 多くのお客様からご要望いただいておりました軸のタイトル設定もこのバージョンからサポートしています。表示角度やフォントサイズ、表示位置などを設定することができます。

         

      • グラデーション サポート – 下図のように単色塗りつぶしではなく、グラデーションでチャートを描画できるようになっています。

      • ドロップ シャドウ効果 – こちらも下図のようにシリーズの要素に対してドロップ シャドウ効果を設定できるようになりました。

      • シリーズのハイライト – エンドユーザーがマウスをホバーさせた際や選択した際にシリーズを強調表示させることができるようになりました。次のシリーズでサポートしています。
        - カテゴリ シリーズ
        - 範囲カテゴリ シリーズ
        - 財務シリーズ

      • ホバー & タッチ インタラクション – マウスやタッチ ジェスチャーにおいてシリーズにポインターを持っていくホバー機能が新たに追加されました。上記のハイライト機能などと組み合わせて利用することができます。また、初回ロード時にアニメーション効果を持たせてチャートを表示させる機能も新たに追加されています。

      • ズームバー / 範囲セレクター – ズームバー、範囲セレクター、時間のナビゲーターとして知られる機能には下図のように別のチャートを貼り付け、上部のチャートの表示領域が全体のどの部分になるかということを視覚的に確認することができるようになりました。

      • KnockoutJS サポート – KnockoutJS を利用したチャート データ表示を簡単に行えるようなサポートを追加しました。

      • パフォーマンスの向上 – インフラジスティックスでは特にグリッドやチャートといった主要なコントロールはもちろん、それ以外のコントロールについても常にパフォーマンス チューニングを行っています。Web ベースのアプリケーションでは特にこのパフォーマンスが重要となる局面が多くなります。このリリースにおいても新しいパフォーマンス向上の仕組みを取り入れています。

      • ツールチップ – シリーズ タイトルや、値、軸の値などチャート要素(点)に関連した情報をツールチップとして表示することができるようになりました。

     

    円チャート

    ラベルの吹き出し線 – 円チャートにおいて各要素のラベルを要素外に表示させることができます。更に要素からラベルへ直線で繋いだり、下図のように曲線で繋ぐことができるようになりました。

     

    レイアウト マネージャー

    2013 Volume 1 において CTP として公開していたレイアウト マネージャが正式版としてサポート開始となりました。このレイアウト マネージャーは jQuery UI ベースのウィジットであり、ページのサイズにコンテンツの領域を合わせたり、コンテンツを配置したりすることができるライブラリーです。

    主要機能

    • 生産性の向上並びに利用の簡易さ - テーブルタグを利用する方法の代替として簡単にレイアウトの設定を行うことが可能になります。

    • レイアウトのカスタマイズ – デザイン フロー、枠線の設定、リサイズの際にアルゴリズムを利用して画面に適合する垂直およびカラムレイアウトの実現

    • インタラクティブ グリッド – 下記のタイル マネージャのようなインタラクティブなレイアウト マネージャーを作成することができるグリッドシステムを提供。

     

    タイル マネージャー

    Web アプリケーションにおいてこれまでのような静的なレイアウトではなく、ある領域の拡大や縮小をサポートするレイアウト ライブラリーです。上記のレイアウト マネージャーの機能をベースとして作成されています。各タイルには、最大化、最小化、一覧表示状態という状態をもち、各切り替え時にコンテンツを変更させることでユーザーにとってその時々に重要なデータを表示させます。こちらも 2013 Volume 1 では CTP として公開しておりましたが、正式版となりました。

    主要機能

    • タイル レイアウト – グリッド パネルのようにタイルを行、列に並べて表示させます。すべてが同じサイズではなく、列・行スパンにも対応しています。また、データバインディングについてもサポートしています。

    • 状態に合わせたカスタマイズ - 下図のようにタイルの状態に合わせて表示されるコンテンツのリサイズや変更が可能になります。

    いかがでしょうか? Flash や Silverlight で実現していたようなインタラクティブな Web アプリケーションを HTML/jQuery を用いて作成することができるようになりました。

    トライアル版のダウンロードはこちら

    download-button

    2013 Volume2 新機能エントリ