在图像查看和编辑WPF上共享冲突 [英] Sharing Violation on image View and Edit WPF
问题描述
我正在处理 MVVM
和 WPF
应用程序。我有一个场景,我必须编辑查看图像并保存它。
我已经使用 RadCarousel
in使用 ContextMenu
右键单击我正在使用 mspaint
编辑图像。当我尝试保存编辑后的图像时,出现 路径共享违例错误
。
图片位于共享文件夹中。
// XAML代码:
< telerik:RadCarousel x:Name =MarketSeriesCarousel
HorizontalAlignment =Stretch
VerticalAlignment =Stretch
ItemsSource ={Binding Path = MarketSeriesImageList, Mode = TwoWay,UpdateSourceTrigger = PropertyChanged,NotifyOnSourceUpdated = True,NotifyOnTargetUpdated = True}
Background =Transparent
HorizontalScrollBarVisibility =Auto
ScrollViewer.CanContentScroll =True
ScrollViewer.VerticalScrollBarVisibility =Auto
telerik:StyleManager.Theme =Windows8
Focusable =True
PropertyChanged =MarketSeriesCarousel_PropertyChanged>
< telerik:RadCarousel.ContextMenu>
< ContextMenu>
< MenuItem Header =EditCommand ={Binding EditImage}CommandParameter ={Binding}/>
< MenuItem Header =MetaDataIsEnabled =False/>
< MenuItem Header =DeleteCommand ={Binding DeleteImage}/>
< / ContextMenu>
< / telerik:RadCarousel.ContextMenu>
< telerik:RadCarousel.ItemsPanel>
< ItemsPanelTemplate>
< telerik:RadCarouselPanel Path ={StaticResource path}
telerik:StyleManager.Theme =Windows8>
< / telerik:RadCarouselPanel>
< / ItemsPanelTemplate>
< / telerik:RadCarousel.ItemsPanel>
< i:EventTrigger EventName =MouseDoubleClick>
< i:InvokeCommandAction Command ={Binding ViewSeriesImage}/>
< / i:EventTrigger>
< / i:Interaction.Triggers>
< / telerik:RadCarousel>
// ViewModel代码:
///< summary>
///编辑图像查看器。
///< / summary>
private void EditImageViewer()
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo(ImagePath);
startInfo.Verb =edit;
Process proc = Process.Start(startInfo);
$ b $ catch(Exception ex)
{
//错误处理。
抛出新的ApplicationException(ex.Message);
}
}
我可以做到这一点吗?或者任何图像编辑的替代品。
但是我需要 mspaint
中的所有功能。
你得到这个错误是因为你的wpf应用程序保持图像文件被锁定,因为你实际上是指它。
要解决此问题,请创建同一个文件的内存位图图像。我使用下面的代码也使用mvvm:
public BitmapImage Image
{
get
{
if(!image_retrieved)getImageAsync();
return _Image;
私有异步任务getImageAsync()
{
image_retrieved = true;
_Image = await ImageFactory.CreateImageAsync(ImageFullPath).ConfigureAwait(true);
this.OnPropertyChanged(()=> Image);
}
public static async任务< BitmapImage> CreateImageAsync(string filename)
{
if(!string.IsNullOrEmpty(filename)&&& File.Exists(filename))
{
try
{
byte [] buffer = await ReadAllFileAsync(filename).ConfigureAwait(false);
System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer);
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = ms;
image.EndInit();
image.Freeze();
返回图片;
}
catch
{
return null;
}
}
else else null;
}
静态异步任务< byte []> ReadAllFileAsync(string filename)
{
尝试
{
使用(var file = new FileStream(FileMode.Open,FileAccess.Read,FileShare.Read,4096,true) )
{
byte [] buff = new byte [file.Length];
await file.ReadAsync(buff,0,(int)file.Length).ConfigureAwait(false);
返回buff;
}
}
catch
{
return null;
$ b然后改变绑定绑定到Image属性。
如果你不需要这样做就可以异步地创建镜像。
I'm working on MVVM
and WPF
application. I have a scenario in which i have to edit the viewing image and save it.
I have used RadCarousel
in which using the ContextMenu
on right click i'm editing the image using mspaint
. When i try to save the edited image i get the "Sharing violation error on path
".
The images are located in a shared folder.
//XAML Code:
<telerik:RadCarousel x:Name="MarketSeriesCarousel"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ItemsSource="{Binding Path=MarketSeriesImageList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True}"
SelectedItem="{Binding SelectedMarketSeriesImage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"
Background="Transparent"
HorizontalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
ScrollViewer.VerticalScrollBarVisibility="Auto"
telerik:StyleManager.Theme="Windows8"
Focusable="True"
PropertyChanged="MarketSeriesCarousel_PropertyChanged">
<telerik:RadCarousel.ContextMenu>
<ContextMenu >
<MenuItem Header="Edit" Command="{Binding EditImage}" CommandParameter="{Binding }"/>
<MenuItem Header="MetaData" IsEnabled="False"/>
<MenuItem Header="Delete" Command="{Binding DeleteImage}"/>
</ContextMenu>
</telerik:RadCarousel.ContextMenu>
<telerik:RadCarousel.ItemsPanel>
<ItemsPanelTemplate>
<telerik:RadCarouselPanel Path="{StaticResource path}"
telerik:StyleManager.Theme="Windows8" >
</telerik:RadCarouselPanel>
</ItemsPanelTemplate>
</telerik:RadCarousel.ItemsPanel>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding ViewSeriesImage}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</telerik:RadCarousel>
//ViewModel Code:
/// <summary>
/// Edit image viewer.
/// </summary>
private void EditImageViewer()
{
try
{
ProcessStartInfo startInfo = new ProcessStartInfo(ImagePath);
startInfo.Verb = "edit";
Process proc = Process.Start(startInfo);
}
catch (Exception ex)
{
// Error handling.
throw new ApplicationException(ex.Message);
}
}
Any possible ways that i can achieve this? Or any alternatives for image editing.
But i need all the functionalities in the mspaint
.
解决方案 You get this error because your wpf application is keeping a the image file locked because you are actually referring to it.
To solve this problem create a memory bitmap image of the same file. I use following code for this also using mvvm :
public BitmapImage Image
{
get
{
if (!image_retrieved) getImageAsync();
return _Image;
}
}
private async Task getImageAsync()
{
image_retrieved = true;
_Image = await ImageFactory.CreateImageAsync(ImageFullPath).ConfigureAwait(true);
this.OnPropertyChanged(() => Image);
}
public static async Task<BitmapImage> CreateImageAsync(string filename)
{
if (!string.IsNullOrEmpty(filename) && File.Exists(filename))
{
try
{
byte[] buffer = await ReadAllFileAsync(filename).ConfigureAwait(false);
System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer);
BitmapImage image = new BitmapImage();
image.BeginInit();
image.CacheOption = BitmapCacheOption.OnLoad;
image.StreamSource = ms;
image.EndInit();
image.Freeze();
return image;
}
catch
{
return null;
}
}
else return null;
}
static async Task<byte[]> ReadAllFileAsync(string filename)
{
try
{
using (var file = new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.Read, 4096, true))
{
byte[] buff = new byte[file.Length];
await file.ReadAsync(buff, 0, (int) file.Length).ConfigureAwait(false);
return buff;
}
}
catch
{
return null;
}
}
Then change your binding to bind to the Image property.
It is doing the image creating asynchronously if you don't need that just do in your gui thread.
这篇关于在图像查看和编辑WPF上共享冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!