Sharing Violation on image View and Edit WPF

2019-08-03 03:12发布

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.

1条回答
forever°为你锁心
2楼-- · 2019-08-03 03:38

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.

查看更多
登录 后发表回答