2013-11-10 81 views
3

這是發生了一個圖片庫WPF應用程序,其中顯示了列表框和所選圖像縮略圖使用XAML異常在FileInfo.Delete - IOException異常

的問題 - 有沒有辦法安全地刪除當前選中的圖像沒有得到IOException?

僅供參考 - 用戶擁有所有權限的目錄,沒有其他進程正在使用該文件

下面的代碼刪除文件

void deleteCurrentlySelectedImageClick() 
{ 
var o = SelectedPhoto; // class MyPhoto with a string FilePath 
string path = o.FilePath; 
// ViewList is of type List<MyPhoto> bound to listbox for displaying thumbnails    
// for the purists 
// it can/should be of type ObservableCollection<> 
// but this doesn't change that often here :) 
ViewList.Remove(o); 
o = null; 
firePropertyChanged("ViewList"); 
firePropertyChanged("SelectedPhoto"); 

FileInfo fi = new FileInfo(path); 
fi.Delete(); 
} 

的例外是

System.IO.IOException was unhandled by user code 
    HResult=-2147024864 
    Message=The process cannot access the file 'C:\<path>\US-wp2.jpg' because it is being used by another process. 
    Source=mscorlib 
    StackTrace: 
     at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath) 
     at System.IO.FileInfo.Delete() 

用於縮略圖的XAML是

<ListBox 
    IsSynchronizedWithCurrentItem="True" 
    Name="PhotosListBox" 
    Style="{StaticResource PhotoListBoxStyle}" 
    Margin="5" 
    SelectionMode="Extended" 
    ItemsSource="{Binding ViewList}" 
    SelectedIndex="0" 
    SelectionChanged="PhotosListBox_SelectionChanged" 
    > 

.... //資源XAML是....

<DataTemplate DataType="{x:Type sample1:MyPhoto}"> 
     <Grid VerticalAlignment="Center" HorizontalAlignment="Center" Margin="6"> 
      <!-- Drop Shadow --> 
      <Border HorizontalAlignment="Stretch" VerticalAlignment="Stretch" CornerRadius="4" Background="#44000000"> 
       <Border.RenderTransform> 
        <TranslateTransform X="5" Y="5" /> 
       </Border.RenderTransform> 
       <Border.BitmapEffect> 
        <BlurBitmapEffect Radius="8" /> 
       </Border.BitmapEffect> 
      </Border> 
      <!-- Image Template --> 
      <Border Padding="4" Background="White" BorderBrush="#22000000" BorderThickness="1"> 
       <StackPanel Orientation="Vertical"> 
        <Image Source="{Binding FilePath}"/> 
       </StackPanel> 
      </Border> 
     </Grid> 
    </DataTemplate> 

     <!-- Main photo catalog view --> 
    <Style TargetType="{x:Type ListBox}" x:Key="PhotoListBoxStyle"> 
     <Setter Property="Foreground" Value="White" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ListBox}" > 
        <WrapPanel Margin="5" IsItemsHost="True" Orientation="Horizontal" 
        ItemHeight="{Binding ElementName=ZoomSlider, Path='Value'}" 
        ItemWidth="{Binding ElementName=ZoomSlider, Path='Value'}" 
        VerticalAlignment="Top" HorizontalAlignment="Stretch" /> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

    <!-- Style for an individual generic item --> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter Property="Background" Value="Transparent" /> 
     <Setter Property="Template"> 
      <Setter.Value> 
       <ControlTemplate TargetType="{x:Type ListBoxItem}" > 
        <Border SnapsToDevicePixels="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="{TemplateBinding Background}"> 
         <ContentPresenter /> 
        </Border> 
        <ControlTemplate.Triggers> 
         <Trigger Property="IsSelected" Value="True"> 
          <Setter Property="Background" Value="#445B6249" /> 
         </Trigger> 
        </ControlTemplate.Triggers> 
       </ControlTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 

全尺寸圖像XAML僅僅是

<Image Source="{Binding SelectedPhoto.FilePath}" HorizontalAlignment="Center" VerticalAlignment="Center" /> 

回答

2

回答你的問題是:沒有,沒有安全刪除文件的方法,你需要處理IOException。可能有多種原因,如:

  • 您可能沒有訪問權限以刪除文件
  • 該文件是由另一個進程使用(某人/某物人打開該文件)
  • 的文件已經被刪除,不存在

在特定情況下,檢查了這個問題:Problems overwriting (re-saving) image when it was set as image source

+0

感謝,更新了上面的問題,簡而言之,用戶是admin,沒有其他進程正在使用該文件,FILE存在並且當前顯示在縮略圖和另一個圖像控件中 – Kumar

+0

您可以嘗試手動刪除文件?那樣有用嗎? – Szymon

+0

我更新了答案 – Szymon

1

您應該關閉/處理圖像的原始文件流。加載時將它們複製到MemoryStrean。

+0

這個綁定是通過使用隱喻完成的,所以沒有MemoryStream來處置 – Kumar

+0

這個作品呢!但選擇的答案是少代碼 – Kumar

+0

庫馬爾我會改變這個比喻。綁定到照片的實際內存副本,而不是保持文件句柄打開。 – atomaras

0
public static bool Delete(FileInfo fi) 
    { 
     int retries = 40; 
     bool ret = false; 
     SpinWait _sw = new SpinWait(); 

     while (!ret && retries-- > 0) 
     { 
      if (fi?.Exists ?? false) 
      { 
       fi.IsReadOnly = false; 
       try 
       { 
        fi.Delete(); 
        ret = true; 
       } 
       catch (IOException) { _sw.SpinOnce(); } 
      } 
      else break; 
     } 
     return ret; 
    } 

如果需要說明,將進行編輯。