2010年2月4日木曜日

第12回 ツールバーのボタンを作る

ツールバーってMVVM的にどう作るんだろ?と悩んでしまいました。
XAMLで直にちょいちょいって書けば早そうですけど、
無駄に(?)MVVMぽく書いてみました。

まず、ツールバーのアイコンとクリック時のコマンドを結びつけるクラス。



 class ImageButton {
  private readonly string _description;
  private readonly ICommand _command;
  private readonly BitmapImage _image;

  public ImageButton(string description, ICommand command, string imageFilePath) {
   _description = description;
   _command = command;
   _image = new BitmapImage();
   _image.BeginInit();
   _image.UriSource = new Uri(imageFilePath, UriKind.RelativeOrAbsolute);
   _image.EndInit();
  }

  #region Property
  /// <summary>
  /// ボタンの機能の説明
  /// </summary>
  public string Description {
   get { return _description; }
  }

  /// <summary>
  /// 押されたときのコマンド
  /// </summary>
  public ICommand Command {
   get { return _command; }
  }

  /// <summary>
  /// ボタンに表示するイメージ
  /// </summary>
  public BitmapImage Image {
   get { return _image; }
  }
  #endregion
 }



前回までついてこれている方なら何も難しくないと思います。
たんにクラス内に各オブジェクトへの関連を持っているだけです。

そしてMainWindowViewModelに実際のボタンのインスタンスを作ります。
今回はとりあえず1個だけ。
オプションダイアログを出します。(今は起動ダイアログとしか役目を果たしていません)
今はこのダイアログは特に意味はないです。



  private RelayCommand _optionDialogCommmand;
  /// <summary>
  /// オプションダイアログを開く
  /// </summary>
  public ICommand OptionDialogCommand {
   get {
    if (_optionDialogCommmand == null) {
     _optionDialogCommmand = new RelayCommand(this.OpenOptionDialog);
    }
    return _optionDialogCommmand;
   }
  }

  private void OpenOptionDialog(object parameter) {
   var dialog = new OptionDialog(_userInfo);
   dialog.ShowDialog();
  }



同じViewModelにそれをObservableCollectionで保持します。



  public ObservableCollection<ImageButton> CommandButtons {
   get { return _commandButtons; }
  }

同Initializeメソッド内


   //ツールバーのボタンの作成
   var baseUri = System.IO.Directory.GetParent(
    System.Reflection.Assembly.GetExecutingAssembly().Location).FullName;
   var commands = new ImageButton[] {
    new ImageButton("設定", OptionDialogCommand,
     baseUri + @"\Icon\spanner_48.png")
   };

   foreach (var comm in commands) {
    _commandButtons.Add(comm);
   }


アイコンは自分で用意してください。(もちろんファイル名はそれに従って変更してください)
http://wefunction.com/2008/07/function-free-icon-set/
こちらのアイコンをダウンロードして使わせていただいています。

最後にMainWindow.xamlに置きます。



 <ToolBar ItemsSource="{Binding Path=CommandButtons}" DockPanel.Dock="Top">
   <ToolBar.ItemTemplate>
    <DataTemplate DataType="{x:Type vm:ImageButton}">
     <Button Command="{Binding Path=Command}">
      <Image Source="{Binding Path=Image}" Height="24" Width="24"/>
     </Button>
    </DataTemplate>
   </ToolBar.ItemTemplate>
  </ToolBar>


やっていることはTabControlの回とほとんど同じですね。
最初に作ったImageButton のプロパティCommandとImageにそれぞれバインドしています。

今回のソースコード
http://wtwitter.codeplex.com/SourceControl/changeset/view/40302

0 件のコメント:

コメントを投稿