UI中显示的图像锁定源文件

时间:2014-10-10 16:26:33

标签: c# wpf image locking datatemplate

我有一个从这里创建的DataTemplate: ComboBoxes sharing Observable Collection keeps breaking

<UserControl.Resources>
    <DataTemplate x:Key="ImageItemTemplate">
        <StackPanel Orientation="Horizontal">
            <Image Height="44" Source="{Binding Path}"/>
            <Label Content="{Binding Name}" VerticalAlignment="Center"/>
        </StackPanel>
    </DataTemplate>
</UserControl.Resources>

<ComboBox x:Name="image1" ItemTemplate="{StaticResource ImageItemTemplate}"/>

代码:

public ObservableCollection<ImageItem> images = new ObservableCollection<ImageItem>();

Generic.ImportGrfx(tabID, image1, images);

public static void ImportGrfx(string tabID, ComboBox combo, ObservableCollection<ImageItem> items)
{
    items.Clear();

    try
    {
        string root = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
        var files = Directory.GetFiles(Path.Combine(root, "input\\" + tabID), "*.png");

        foreach (var file in files)
        {
            ImageItem item = new ImageItem();
            item.Path = file;
            item.Name = Path.GetFileName(file).Remove(Path.GetFileName(file).Length - 4);

            items.Add(item);
        }
    }
    catch (Exception) { }

    combo.ItemsSource = items;
}

public class ImageItem
{
    public string Path { get; set; }
    public string Name { get; set; }
}

我遇到的问题是将这些图像绑定到datatemplate,“锁定”图像源。意思是我无法在程序运行时编辑图像...我会收到错误,说明图像正在使用中。有办法解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

这是Image的骨架,无论何时从外部修改它都会得到更新。

  • 您设置了源,它将其复制到临时路径并从那里加载图像
  • 它会监视初始图像的变化并再次自我更新
  • 冲洗并重复:D

如果您只需要从外部编辑图像,就可以使用自动更新功能。

这是非常基本的,所以随时改进......

enter image description here

代码:

using System;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;

namespace WpfApplication4
{
    /// <summary>
    ///     Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            Loaded += MainWindow_Loaded;
        }


        private void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            DynamicImage1.SetSource(@"d:\Untitled.png");
        }
    }

    internal class DynamicImage : Image
    {
        private string _name;
        private FileSystemWatcher _watcher;

        public void SetSource(string fileName)
        {
            if (fileName == null) throw new ArgumentNullException("fileName");

            if (_watcher != null)
            {
                _watcher.Changed -= watcher_Changed;
                _watcher.Dispose();
            }
            string path = Path.GetDirectoryName(fileName);
            _watcher = new FileSystemWatcher(path);
            _watcher.EnableRaisingEvents = true;
            _watcher.Changed += watcher_Changed;
            _name = fileName;
            string tempFileName = Path.GetTempFileName();
            File.Copy(fileName, tempFileName, true);
            Source = new BitmapImage(new Uri(tempFileName));
        }

        private void watcher_Changed(object sender, FileSystemEventArgs e)
        {
            bool b = string.Equals(e.FullPath, _name, StringComparison.InvariantCultureIgnoreCase);
            if (b)
            {
                string tempFileName = Path.GetTempFileName();
                File.Copy(e.FullPath, tempFileName, true);

                Dispatcher.BeginInvoke((Action) (() => { Source = new BitmapImage(new Uri(tempFileName)); }));
                _name = e.FullPath;
            }
        }
    }
}

XAML:

<Window x:Class="WpfApplication4.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wpfApplication4="clr-namespace:WpfApplication4"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
      <wpfApplication4:DynamicImage x:Name="DynamicImage1" />

    </Grid>
</Window>