PR

ListBoxに表示された画像をポップアップメニューから削除する+1つのサンプル

2013年2月8日(金)
薬師寺 国安

今回は2つのサンプルを紹介します。「ListBoxに表示された画像をポップアップメニューから削除する」と「複数の画像を連続表示する」の2つです。

まずは、「ListBoxに表示された画像をポップアップメニューから削除する」サンプルから紹介します。

ListBoxに表示された画像をポップアップメニューから削除する

このサンプルは、ListBoxに表示されている任意の画像を選択し、マウスの右クリックで表示されるポップアップメニューから、「画像の削除」をクリックすると、選択されていた画像が削除されるというものです(図1)。「画像の削除」を実行する際には、必ず削除する画像を選択状態にして実行してください。なお、今回もピクチャライブラリ内の画像を使用しますので、ピクチャライブラリ内に何枚かの画像を配置しておいてください。

図1:ListBox内の任意の画像を削除した(クリックで拡大)

実際に動かした動画は下記のようになります。Windows Store Applicationの動画を撮るアプリケーションが存在していませんので、スマホで撮った動画です。見難い点はご了承願います。

サンプル一式は、会員限定特典としてダウンロードできます。記事末尾をご確認ください。

プロジェクトの作成

VS 2012のメニューから[ファイル(F)/新規作成(N)/プロジェクト(P)]と選択します。次に、「テンプレート」から「Windows ストア」を選択し、右に表示される項目名から「新しいアプリケーション(XAML)」を選択します。「名前(N)」に任意のプロジェクト名を指定します。ここでは「Win8_DeleteImageFile」という名前を付けています。

コントロールの配置

ツールボックスからデザイン画面上にListBoxコントロールを1個配置します。

書き出されるXAMLコードは省略します。レイアウトは図2になります。

図2:ListBoxコントロールを配置した(クリックで拡大)

ピクチャライブラリへのアクセス許可の設定

今回のサンプルは、ピクチャライブラリにアクセスしますので、「画像ライブラリ」へのアクセス許可が必要になります。ソリューションエクスプローラー内にpackage.appxmanifestというファイルがありますので、このファイルをダブルクリックします。「機能」タブをクリックして、表示される画面の「機能:」にある、「画像ライブラリ」にチェックを付けます(図3)。

図3:package.appxmanifestファイルを開き「画像ライブラリ」にチェックを付ける(クリックで拡大)

次に、ソリューションエクスプローラー内のMainWindow.xamlを展開して表示される、MainWindow.xaml.vbをダブルクリックしてリスト1のコードを記述します。

ロジックコードを記述する

リスト1 (MainWindow.xaml.vb)

Option Strict On

ファイル、フォルダー、およびアプリケーションの設定を管理するクラスの含まれる、Windows.Storage名前空間をインポートします。

Imports Windows.Storage

PopupMenuであるコンテキストメニューを表示させるのに必要なクラスの含まれる、Windows.UI.Popups名前空間をインポートします。

Imports Windows.UI.Popups
Public NotInheritable Class MainPage
  Inherits Page

フォルダーとその内容についての情報を提供する、StorageFolderクラス型のメンバ変数、myPictureFolderを宣言します。

  Dim myPictureFolder As StorageFolder

文字列型の新しいリストであるfileNameメンバ変数を宣言します。

  Dim fileNameList As New List(Of String)

ページがアクティブになった時の処理

ListBox内に画像の一覧を表示するDataShowプロシージャを実行します。

  Protected Overrides Sub OnNavigatedTo(e As Navigation.NavigationEventArgs)
    DataShow()
  End Sub

ListBox内にピクチャライブラリ内の画像を表示する処理

ピクチャライブラリにアクセスします。GetFilesAsyncメソッドで、ピクチャライブラリ内のファイルを取得し、コレクション変数myPictureFilesに格納しておきます。
ListBox内を一度クリアしておきます。この処理をしていないと、画像が重複して表示されますので、ご注意ください。

ファイル名を格納しているmyPictureFilesコレクション内のファイルを、変数myFileに格納しながら、反復処理を行います。
BitmapImageクラスの新しいインスタンスbmpオブジェクトを作成し、SetSourceメソッドに、Await myFile.OpenReadAsyncと指定して、ランダムアクセス用ストリームを開いていきます。また、文字列のリストであるfileNameListオブジェクトにAddメソッドでパス付きファイル名を追加していきます。

Imageの新しいインスタンスmyImageオブジェクトを作成します。
WidthとHeightを指定し、Sourceプロパティにbmpオブジェクトを指定します。
ListBoxコントロールにAddメソッドでmyImageファイルオブジェクトを追加します。これで、ListBoxコントロール内にピクチャライブラリ内の画像一覧が表示されます。

非同期処理で行われるため、メソッドの先頭にAsyncを追加します。Asyncが追加されていると、その処理が非同期で行われることを意味します。

  Private Async Sub DataShow()
    myPictureFolder = KnownFolders.PicturesLibrary
    Dim myPictureFiles As IReadOnlyList(Of IStorageFile) = Await myPictureFolder.GetFilesAsync()
    ListBox1.Items.Clear()
    For Each myFile In myPictureFiles
      Dim bmp As New BitmapImage
      bmp.SetSource(Await myFile.OpenReadAsync)
      fileNameList.Add(Path.GetFileName(myFile.Path))
      Dim myImage As New Image
      myImage.Margin = New Thickness(0, 0, 0, 0)
      myImage.Width = 320
      myImage.Height = 240
      myImage.Source = bmp
      ListBox1.Items.Add(myImage)
    Next
  End Sub

ListBox上にポインターがあった時、右タップの入力刺激があった時の処理

2次元空間でのXとY座標のペアを表すPoint構造体を、右タップされた時点のXとY座標で初期化します。位置合わせを行っています。

ListBoxの描画時の幅と高さで初期化された、新しいSizeのインスタンスmySizeオブジェクトを作成します。Size構造体はオブジェクトの幅と高さを表します。

四角形の幅、高さ、および原点を表すRect構造体を、Point構造体のオブジェクトmyPointと、Size構造体のオブジェクトmySizeで初期化した、新しいRectのインスタンス、myRectオブジェクトを作成します。

コンテキストメニューを表すPopupMenuクラスのインスタンス、myPopupオブジェクトを作成します。

Command.Addメソッドで、PopupMenuに項目名と、その項目をタップした際のコマンドを追加します。UICommandクラスは、コンテキストメニュー内のコマンドを表します。PopupMenuに「画像の削除」の項目を追加し、それに対するコマンド(ImageDelete)を追加します。

ShowForSelectionAsyncメソッドで、指定された選択項目を基準とする適切な位置に、コンテキストメニューを表示します。この場合はListBox内で右タップがされた位置の左側(Placement.Left)にコンテキストメニューが表示されます。Placement列挙体については、下記のURLを参考にしてください。
→ Placement enumeration (Windows)

非同期処理で行われるため、メソッドの先頭にAsyncを追加します。Asyncが追加されていると、その処理が非同期で行われることを意味します。

  Private Async Sub ListBox1_RightTapped(sender As Object, e As RightTappedRoutedEventArgs) Handles ListBox1.RightTapped
    Dim myPoint As Point = New Point(e.GetPosition(ListBox1).X + ListBox1.Width, e.GetPosition(ListBox1).Y - (ListBox1.Height / 2))
    Dim mySize As New Size(ListBox1.ActualWidth, ListBox1.ActualHeight)
    Dim myRect As New Rect(myPoint, mySize)
 
    Dim myPopup As New PopupMenu

    myPopup.Commands.Add(New UICommand("画像の削除", Sub(command)
                                                     ImageDelete()
                                           End Sub))
    Await myPopup.ShowForSelectionAsync(myRect, Placement.Left)
  End Sub

選択された画像を削除する処理

ListBoxコントロール内の画像が選択状態になっていない場合は、警告メッセージを表示して、処理を抜けます。

それ以外の場合は、以下の処理を行います。ファイル名を格納しているリストオブジェクトである、fileNameListで、ListBoxのインデックスに対応するファイルを、GetFileAsyncメソッドで取得し、DeleteImageFileに格納します。
リストであるfileNameListからListBoxのインデックスに対応するファイル名を、RemoveAtメソッドで削除します。
同様に、DeleteFileAsyncメソッドで、DeleteImageFileに格納されているファイルを削除します。
削除した旨のメッセージを表示し、ListBox内を更新するためにDataShowプロシージャを実行します。

非同期処理で行われるため、メソッドの先頭にAsyncを追加します。Asyncが追加されていると、その処理が非同期で行われることを意味します。

  Private Async Sub ImageDelete()
    If ListBox1.SelectedIndex < 0 Then
      Dim message = New MessageDialog("画像を選択してください。")
      Await message.ShowAsync
      Exit Sub
    Else
  
      Dim DeleteImageFile = Await myPictureFolder.GetFileAsync(fileNameList(ListBox1.SelectedIndex))
      fileNameList.RemoveAt(ListBox1.SelectedIndex)
      Await DeleteImageFile.DeleteAsync()
      Dim message = New MessageDialog("削除しました。")
      Await message.ShowAsync
      DataShow()
    End If
  End Sub
End Class
Think IT会員限定特典
  • ListBoxに表示された画像をポップアップメニューから削除するWindowsアプリ

  • 複数の画像を連続表示する

薬師寺国安事務所

薬師寺国安事務所代表。Visual Basic プログラミングと、マイクロソフト系の技術をテーマとした、書籍や記事の執筆を行う。
1950年生まれ。事務系のサラリーマンだった40歳から趣味でプログラミングを始め、1996年より独学でActiveXに取り組む。1997年に薬師寺聖とコラボレーション・ユニット PROJECT KySS を結成。2003年よりフリーになり、PROJECT KySS の活動に本格的に参加、.NETやRIAに関する書籍や記事を多数執筆する傍ら、受託案件のプログラミングも手掛ける。Windows Phoneアプリ開発を経て、現在はWindows ストア アプリを多数公開中

Microsoft MVP for Development Platforms - Client App Dev (Oct 2003-Sep 2012)。Microsoft MVP for Development Platforms - Windows Phone Development(Oct 2012-Sep 2013)。Microsoft MVP for Development Platforms - Client Development(Oct 2013-Sep 2014)。Microsoft MVP for Development Platforms-Windows Platform Development (Oct 2014-Sep 2015)。

連載バックナンバー

Think IT会員サービス無料登録受付中

Think ITでは、より付加価値の高いコンテンツを会員サービスとして提供しています。会員登録を済ませてThink ITのWebサイトにログインすることでさまざまな限定特典を入手できるようになります。

Think IT会員サービスの概要とメリットをチェック

他にもこの記事が読まれています