Quantcast
Channel: かずきのBlog@hatena
Viewing all articles
Browse latest Browse all 1387

WPFで画像表示時にファイルをロックしないようにしたい

$
0
0

ネタ元

ListBox にイメージをデータバインドした時に画像を削除する方法

確かにWPFでImageのSourceにstringをBindingしたときは、ファイルがしばらくロックされちゃって困ることがあります。これをロックされないようにするには、自前のコンバーターでファイルロックをしないようにする必要があります。

ロックされる版のアプリ

以下のようにピクチャーフォルダのjpgへのパスをDataContextにつっこみます。

using System;
using System.IO;
using System.Linq;
using System.Windows;

namespace ImageApp
{
    /// <summary>/// MainWindow.xaml の相互作用ロジック/// </summary>publicpartialclass MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            var picturesFolderPath = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
            this.DataContext = Directory.GetFiles(picturesFolderPath, "*.jpg", SearchOption.AllDirectories)
                .ToArray();
        }
    }
}

そして、それをListBoxのItemsSourceにバインドしてItemTemplateでImageのSourceにバインドします。

<Window x:Class="ImageApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:ImageApp"mc:Ignorable="d"Title="MainWindow"Height="350"Width="525"><Grid><ListBox ItemsSource="{Binding}"><ListBox.ItemTemplate><DataTemplate><Image Source="{Binding}"Height="50" /></DataTemplate></ListBox.ItemTemplate></ListBox></Grid></Window>

実行すると以下のように表示されます。

f:id:okazuki:20150620121402p:plain

このときファイルを消そうとすると以下のようにロックされてることが確認できます。

f:id:okazuki:20150620121537p:plain

ロックされないようにする

デフォルトのコンバーターがダメなので自前コンバーターを仕込みます。

using System;
using System.Globalization;
using System.IO;
using System.Windows.Data;
using System.Windows.Media.Imaging;

namespace ImageApp
{
    publicclass ImageConverter : IValueConverter
    {
        publicobject Convert(objectvalue, Type targetType, object parameter, CultureInfo culture)
        {
            var path = (string)value;
            using (var fs = new FileStream(path, FileMode.Open))
            {
                var decoder = BitmapDecoder.Create(
                    fs,
                    BitmapCreateOptions.None,
                    BitmapCacheOption.OnLoad);
                var bmp = new WriteableBitmap(decoder.Frames[0]);
                bmp.Freeze();
                return bmp;
            }
        }

        publicobject ConvertBack(objectvalue, Type targetType, object parameter, CultureInfo culture)
        {
            thrownew NotImplementedException();
        }
    }
}

参考: http://pieceofnostalgy.blogspot.jp/2012/02/wpf-bitmapsource.html

あとは、このConverterをImageのSourceに設定します。

<Window x:Class="ImageApp.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:ImageApp"mc:Ignorable="d"Title="MainWindow"Height="350"Width="525"><Window.Resources><local:ImageConverter x:Key="ImageConverter"/></Window.Resources><Grid><ListBox ItemsSource="{Binding}"><ListBox.ItemTemplate><DataTemplate><Image Source="{Binding Converter={StaticResource ImageConverter}}"Height="50" /></DataTemplate></ListBox.ItemTemplate></ListBox></Grid></Window>

実行するとちゃんと画像が表示されて、画像の削除もできるようになります。


Viewing all articles
Browse latest Browse all 1387

Trending Articles



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