2013年2月23日土曜日

テンプレートを使ってみる

参照の追加やusingの記述などで同じような記述を毎回するのは面倒なので、VisualStudioのテンプレート機能を使ってみました

カスタマイズはいろいろ出来るようですが、理解できなかったのでとりあえず...
1. 適当なソリューションを新規作成する("Templete"という名前で良い...特に後で影響しないようなのでなんでもよいようです)
2.  参照やusingの記述をしたり、毎回追加するファイルを追加しておくなどを行う(MVVMなら***ViewModel.csとか)
3. "ファイル" -> "テンプレートのエクスポート"を選択
4. ダイアログが出るのでひたすらデフォルトで"次へ"
5. どこかにzipファイルで出力される模様
> 追記 : MyDocumentsの↓の位置にzipファイルとして作成される
> C:\Users\xxxxx\Documents\Visual Studio 2012\Templates\ProjectTemplates\Visual C#
> 別のマシンで使う場合は同じ場所にコピーすれば使えるみたい

使う場合は、ふつーに新規プロジェクトの作成をしようとすると↑で作成したテンプレートが下の方に表示されるのでそちらを選択すると、いい感じでTemplateで作成した内容がデフォルトになったプロジェクトが生成される模様
(namespaceなどは新規作成にあわせてくれるという意味で)

カスタマイズは奥が深いみたいですが、↑の程度でも適当に使えるので活用してみようかと思います



2013年2月7日木曜日

XAML内でのデータバインド

最も簡単な例として、定番の"スライダーとテキストをbind"してみました

<Window x:Class="_130206_xamlDataBind.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <StackPanel>
            <Slider VerticalAlignment="Top" HorizontalAlignment="Center" Width="300" Margin="10"
                    Name="slider" Value="{Binding textValue}" />
            <TextBlock VerticalAlignment="Top" HorizontalAlignment="Center"
                    Text="{Binding ElementName=slider, Path=Value}" />
        </StackPanel>
    </Grid>
</Window>

2013年2月4日月曜日

BehaviorでViewからViewModelのコマンドを実行&パラメータ渡し

ViewからViewModelのコマンドを実行する際に、Behaviorというものを使う方法があるとのことですので動かしてみました(丸パクリですが...)

手順としては
1. 参照設定の追加
Blendの機能なので、Interactivity.dllを参照する
"プロジェクトの参照設定"の"ブラウズ"にて"参照(B)"から
C:\Program Files (x86)\Microsoft SDKs\Expression\Blend\.NETFramework\v4.0\Libraries
の以下の2つのdllを追加
Microsoft.Expression.Interactions.dll
System.Windows.Interactivity.dll
を選択して"追加"する

2. ***Behavior.cs を作成(ここにbeheviorの処理を書いていきたい)

3. usingを追加
using System.Windows.Interactivity;         // 追加
using Microsoft.Expression.Interactivity;   // 追加

4. 監視対象の型のBehaviorを継承したクラスを作成
using が足りないので以下を追加
using System.Windows.Controls;      // コントロール名称を参照する為
using System.Windows;               // DependencyPropertyの定義

監視対象の型のBehaviorを継承したクラスを作成
    public class TestBehavior : Behavior<Button>

5. 依存関係プロパティの定義と登録
作成したクラス内に依存関係プロパティを登録するコードを追加
戻りは"依存関係プロパティ識別子"で"後でプログラムで値を設定したり、メタデータを取得したりする際に、この識別子を使用して依存関係プロパティを参照できます"とのこと
        public static readonly DependencyProperty MessageProperty =
            DependencyProperty.Register("Message" , typeof(string), typeof(TestBehavior),
                            new UIPropertyMetadata(null));

6. (登録される)依存関係プロパティ
        // 公開プロパティ
        private string _message;
        public string Message
        {
            get { return (string)GetValue(MessageProperty); }
            set { SetValue(MessageProperty, value); }
        }

7. 独自ハンドラ(イベント発生時にやりたいこと)追加
        private void Aleart(object sender, EventArgs e)
        {
            if(!string.IsNullOrEmpty(this.Message)){
                MessageBox.Show(this.Message);
            }
        }

8. アタッチ・デタッチ時のハンドラを登録
        /// <summary>
        /// アタッチされた時の処理
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.Click += Alert;
        }

        /// <summary>
        /// デタッチされた時の処理
        /// </summary>
        protected override void OnDetaching()
        {
            base.OnDetaching();
            this.AssociatedObject.Click -= Alert;
        }
9. xamlにBehaviorを呼び出す処理を記載
            <Button Content="Button" HorizontalAlignment="Left" Margin="8,8,0,0" VerticalAlignment="Top" Width="75">
                <i:Interaction.Behaviors>
                    <local:TestBehavior Message="メッセージを渡す"/>
                </i:Interaction.Behaviors>
            </Button>


とりあえずこれで
- ボタンをクリックした時にBehavior側の処理を呼び出す
という事が出来るようです

BreakPointを適当に張ってみると
1. 起動時にアタッチのハンドラが呼ばれる
  ここで"ボタンクリックイベントにメソッドが登録される"模様
2. ボタンを押下すると登録されたメソッドが呼ばれる
  この時、すでに依存関係プロパティにはxaml側の
  "Message="メッセージを渡す"
  という部分が反映されている
という動きの模様

動かしたソースは以下の通り
TestBehavior.cs側
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows.Interactivity;         // 追加
using Microsoft.Expression.Interactivity;   // 追加

using System.Windows.Controls;      // コントロール名称を参照する為
using System.Windows;               // DependencyPropertyの定義

using System.Diagnostics;

namespace BehaviorTest
{
    public class TestBehavior : Behavior<Button>
    {
        // 依存関係プロパティの登録
        public static readonly DependencyProperty MessageProperty =
            DependencyProperty.Register("Message", typeof(string), typeof(TestBehavior),
                                        new UIPropertyMetadata(null));

        // 登録される依存関係プロパティ
        public string Message
        {
            get { return (string)GetValue(MessageProperty); }
            set { SetValue(MessageProperty, value); }
        }
       
        /// <summary>
        /// アクションハンドラの記載(ボタン押下時に実行)
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Alert(object sender, EventArgs e)
        {
            MessageBox.Show(this.Message);
        }

        /// <summary>
        /// アタッチされた時の処理
        /// </summary>
        protected override void OnAttached()
        {
            base.OnAttached();
            this.AssociatedObject.Click += Alert;
        }

        /// <summary>
        /// デタッチされた時の処理
        /// </summary>
        protected override void OnDetaching()
        {
            base.OnDetaching();
            this.AssociatedObject.Click -= Alert;
        }
    }
}


xaml側のコード
<Window x:Class="BehaviorTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
       
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
        xmlns:local="clr-namespace:BehaviorTest"
        >
    <!-- 上記Title以下の2行追加 -->
    <Grid>
        <StackPanel>
            <Button Content="Button" HorizontalAlignment="Left" Margin="8,8,0,0" VerticalAlignment="Top" Width="75">
                <i:Interaction.Behaviors>
                    <local:TestBehavior Message="メッセージを渡す"/>
         <!-- ↑の"Message"がコードにバインドされている模様 -->
                </i:Interaction.Behaviors>
            </Button>
        </StackPanel>
    </Grid>
</Window>