加载图像时的MVVM WPF Fire命令(在加载的事件上)

时间:2017-10-05 13:50:31

标签: c# wpf visual-studio-2008 icommand

我的视图中有一个WPF图像控件。加载图像时,我想触发在模型视图中定义和执行的事件。我怎样才能做到这一点?我不知道如何使用命令执行此操作。

<Image Grid.Row="0" 
       Source="{Binding Path=ImageSrc,  NotifyOnTargetUpdated=True, Converter={StaticResource imgToSrcConverter}}" 
       Visibility="{Binding ImgVisibility}" 
       RenderTransformOrigin="0,0"
       SnapsToDevicePixels="True"
       OverridesDefaultStyle="False"
       TargetUpdated="targetUpdated" 
       Cursor="Hand"
       RenderOptions.BitmapScalingMode="LowQuality"
       RenderOptions.EdgeMode="Aliased">
<Image.Effect>
        <DropShadowEffect Opacity="0.8" BlurRadius="8">                
        </DropShadowEffect>
    </Image.Effect>
</Image>

转换器

public class ImgToSrcConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
    {
        Image image = value as Image;
        if (image != null)
        {
            MemoryStream ms = new MemoryStream();
            image.Save(ms, image.RawFormat);
            ms.Seek(0, SeekOrigin.Begin);
            BitmapImage bi = new BitmapImage();
            bi.BeginInit();
            bi.StreamSource = ms;
            bi.EndInit();
            return bi;
        }
        return null;
    }

    public object ConvertBack(object value, Type targetType,
        object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

查看模型

        public Image ImageSrc
        {
            get
            {
                MemoryStream ms = new MemoryStream(GetImageAsByteArray());
                Image img = Image.FromStream(ms);

                // Here I call method to hide splash screen "Loading"

                return img;
            }
        }

3 个答案:

答案 0 :(得分:0)

您可以在后台加载图片并在加载图片时调用“NotifyPropertyChanged”:

private static Image SplashScreenImage = GetSplashScreenImage();
private Image ActualImage = null;
private bool IsLoading = false;
public Image ImageSrc
{
    get
    {
        if (ActualImage != null)
            return ActualImage;

        if (!IsLoading)
        {
            IsLoading = true;
            // start loading image in background
            Task.Run(() =>
            {
                MemoryStream ms = new MemoryStream(GetImageAsByteArray());
                ActualImage = Image.FromStream(ms);
            }).ContinueWith(t => PropertyChanged("ImageSrc"), TaskScheduler.FromCurrentSynchronizationContext());
        }
        return SplashScreenImage;
    }
}

答案 1 :(得分:-1)

您可以使用不带转换器的异步绑定:

<Image Source="{Binding ImageSrc, IsAsync=True}"/>

ImageSrc属性getter直接创建一个BitmapFrame或BitmapImage,如下所示:

public ImageSource ImageSrc
{
    get
    {
        ImageSource image;

        using (var stream = new MemoryStream(GetImageAsByteArray()))
        {
            image = BitmapFrame.Create(
                stream, BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
        }

        SplashScreenEnabled = false;
        return image;
    }
}

public bool SplashScreenEnabled { get; set; } // firing PropertyChanged omitted

答案 2 :(得分:-1)

如果要在Loaded元素的Image事件触发时调用命令,则可以使用交互触发器:

<Image Grid.Row="0" 
           Source="{Binding Path=ImageSrc,  NotifyOnTargetUpdated=True, Converter={StaticResource imgToSrcConverter}}" 
           Visibility="{Binding ImgVisibility}" 
           RenderTransformOrigin="0,0"
           SnapsToDevicePixels="True"
           OverridesDefaultStyle="False"
           TargetUpdated="targetUpdated" 
           Cursor="Hand"
           RenderOptions.BitmapScalingMode="LowQuality"
           RenderOptions.EdgeMode="Aliased"
           xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding YourCommand}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
    <Image.Effect>
        <DropShadowEffect Opacity="0.8" BlurRadius="8">
        </DropShadowEffect>
    </Image.Effect>
</Image>

有关如何通过执行视图模型命令来处理事件的更多信息,请参阅以下博客文章:https://blog.magnusmontin.net/2013/06/30/handling-events-in-an-mvvm-wpf-application/

另一种选择可能是简单地从源属性的setter执行命令:

public Image ImageSrc
{
    get
    {
        MemoryStream ms = new MemoryStream(GetImageAsByteArray());
        Image img = Image.FromStream(ms);

        YourCommandProperty.Execute(null);

        return img;
    }
}