如何在雙向綁定的Image控件上繪製自定義標記(wpf)

咱們的需求是什麼?

答:須要在圖片上增長一些自定義標記,例如:2個圖片對比時,對相同區域進行高亮。網絡

先上效果圖:

 

 

 

設計思路

1.概述

1.經過TargeUpdated事件,從新繪製圖片進行替換。異步

2.詳細實現

1.咱們先綁定ImageTargetUpdated事件。設計

<Image x:Name="DestImageControl" Source="{Binding Path=Source.Url, NotifyOnTargetUpdated=True}" TargetUpdated="ImageTargetUpdated">

根據微軟官方文檔,如上圖,咱們須要設置NotifyOnRargetUpdated的值,官方文檔以下:雙向綁定

 

 

 2.在響應方法中,對圖像進行繪製。調試

private void ImageTargetUpdated(object sender, DataTransferEventArgs e)
{
    //todo:繪製圖像:drawingImage = DrawImage......
    //設置新圖像:DestImageControl.SetCurrentValue(Image.SourceProperty, drawingImage);
}

 

3.按照上面的思路,很完美,因而咱們遇到了問題

什麼?有什麼問題?在直接讀取Image控件的Source時,咱們發現它是沒有值的,因此咱們繪製的圖片底圖是沒有的。code

下面咱們來分析一下:

因爲Image控件的Source咱們是綁定的Url(相似:http://xxx.xxx.com/xxx.jpg),因此wpf會進行一步下載,經過調試,咱們會發現它此時的類是LateBoundBitmapDecoder。對象

關於類LateBoundBitmapDecoder的官方文檔以下:blog

 

 

 

咱們發現,這個類加載圖片是異步的。因此咱們在TargeUpdated事件中直接拿到的Source,此時僅僅是一個空對象,他的數據還在網絡中傳輸。知道原理就好辦了。事件

咱們對Source綁定下載完成事件!圖片

if (((BitmapFrame)imageControl.Source).IsDownloading)
{
    //若是是異步下載,則綁定下載完成後事件
    ((BitmapFrame)imageControl.Source).Decoder.DownloadCompleted += (sender2, e2) =>
    {
        BitmapSource sourceImg = (BitmapSource)((LateBoundBitmapDecoder)sender2).Frames[0];
        DrawImage(sourceImg);
    };
}
else
{
    //若是已存在圖片,則直接使用
    BitmapSource sourceImg = (BitmapSource)imageControl.Source;
    DrawImage(sourceImg);
}

 

再試運行一下,就和最前面的效果圖一致了。

總結

1.對於雙向綁定的Image控件,咱們在原圖上增長內容時,能夠響應TargeUpdated事件進行自定義繪製。

2.在TargeUpdated事件響應中,有可能拿不到Source,此時,咱們須要綁定下載完成事件,在事件中進行底圖的獲取。

3.咱們須要使用SetCurrentValue方法對Source進行賦值,如此不會影響雙向綁定。

 

PS:

1.此文僅介紹遇到問題的解決思路及解決過程,並不分享源碼。

相關文章
相關標籤/搜索