1

为什么图像不显示?是我的代码错了吗?

视图中的 xml 代码:

<UserControl x:Class="AllSample.Views.LoadImageView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:vm="clr-namespace:AllSample.ViewModels"
         mc:Ignorable="d" >
<UserControl.Resources>
     <vm:LoadImageViewModel x:Key="LoadImageViewModel"></vm:LoadImageViewModel>
</UserControl.Resources>
<StackPanel FlowDirection="RightToLeft" DataContext="{Binding Source={StaticResource LoadImageViewModel}}">

            <Image Source="{Binding ImageSource,Mode=TwoWay}" Margin="20 20" Stretch="Fill" Height="200" Width="300"></Image>
        <Button Command="{Binding LoadImageCommand}" Margin="60 20"  Content="Load Image"></Button>
</StackPanel>

视图模型代码:

using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using AllSample.Annotations;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;

namespace AllSample.ViewModels
{
    public class LoadImageViewModel : INotifyPropertyChanged
    {
        private ImageSource _imageSource;

        public LoadImageViewModel()
        {
            LoadImageCommand = new RelayCommand(LoadImage, CanMoveFirstCommand);
        }

        public RelayCommand LoadImageCommand { get; private set; }

        public ImageSource ImageSource
        {
            get { return _imageSource; }
            set
            {
                if (Equals(value, _imageSource)) return;
                _imageSource = value;
                OnPropertyChanged("ImageSource");
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        private void LoadImage()
        {
            var openFileDialog = new OpenFileDialog();
            if (openFileDialog.ShowDialog() != true) return;
            Stream reader = File.OpenRead(openFileDialog.FileName);
            Image photo = Image.FromStream(reader);

            var finalStream = new MemoryStream();
            photo.Save(finalStream, ImageFormat.Png);

            // translate to image source
            var decoder = new PngBitmapDecoder(finalStream, BitmapCreateOptions.PreservePixelFormat,
                                               BitmapCacheOption.Default);

            _imageSource = decoder.Frames[0];
        }

        private bool CanMoveFirstCommand()
        {
            return true;
        }

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

编辑。 我们不需要以下行:我们不需要以下行:我们不需要以下行:我们不需要以下行:

 public ImageSource ImageSource
    {
        get { return _imageSource; }
        set
        {
            if (Equals(value, _imageSource)) return;
            _imageSource = value;
            OnPropertyChanged("ImageSource");
        }
    }

ViewModel 中的正确代码:

namespace AllSample.ViewModels
{
    public class LoadImageViewModel : INotifyPropertyChanged
    {
        public LoadImageViewModel()
        {
            LoadImageCommand = new RelayCommand(LoadImage, CanMoveFirstCommand);
        }

        public RelayCommand LoadImageCommand { get; private set; }

        public ImageSource ImageSource { get; private set; }

        public event PropertyChangedEventHandler PropertyChanged;

        private void LoadImage()
        {
            var openFileDialog = new OpenFileDialog();
            if (openFileDialog.ShowDialog() != true) return;
            Stream reader = File.OpenRead(openFileDialog.FileName);
            Image photo = Image.FromStream(reader);
            var finalStream = new MemoryStream();
            photo.Save(finalStream, ImageFormat.Png);

            // translate to image source
            var decoder = new PngBitmapDecoder(finalStream, BitmapCreateOptions.PreservePixelFormat,
                                               BitmapCacheOption.Default);

            ImageSource = decoder.Frames[0];
            OnPropertyChanged("ImageSource");
        }
        private static bool CanMoveFirstCommand()
        {
            return true;
        }

        [NotifyPropertyChangedInvocator]
        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
4

2 回答 2

3

这条线

_imageSource = decoder.Frames[0];

LoadImage方法上是错误的。

您需要设置 Property ImageSource,以便PropertyChanged引发该属性的 -Event 。

将其更改为

ImageSource = decoder.Frames[0];
于 2013-04-26T23:04:08.370 回答
0

我认为这是更合适的代码:

视图模型代码:

public class LoadImageViewModel : INotifyPropertyChanged
{
    private readonly IOService _ioService;
    public LoadImageViewModel(IOService ioService)
    {
        _ioService = ioService;
        LoadImageCommand = new RelayCommand(GetImage, () => true);
    }

    public RelayCommand LoadImageCommand { get; private set; }

    public ImageSource ImageSource { get; private set; }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    public void GetImage()
    {
        string fileName = _ioService.GetFilePath();
        if (string.IsNullOrEmpty(fileName)) return;
        Stream reader = File.OpenRead(fileName);
        Image photo = Image.FromStream(reader);
        var finalStream = new MemoryStream();
        photo.Save(finalStream, ImageFormat.Png);
        var decoder = new PngBitmapDecoder(finalStream, BitmapCreateOptions.PreservePixelFormat,
                                           BitmapCacheOption.Default);

        ImageSource = decoder.Frames[0];
        OnPropertyChanged("ImageSource");
    }
}
public class Dialogs : IOService
{
    public string GetFilePath()
    {
        var openFileDialog = new OpenFileDialog();
        return openFileDialog.ShowDialog() != true ? string.Empty : openFileDialog.FileName;
    }
}
public interface IOService
{
    string GetFilePath();
}

查看代码:

<UserControl x:Class="AllSample.Views.LoadImageView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:vm="clr-namespace:AllSample.ViewModels"
         mc:Ignorable="d" >
<UserControl.Resources>
    <ObjectDataProvider x:Key="LoadImageViewModel"
                        ObjectType="{x:Type vm:LoadImageViewModel}">
        <ObjectDataProvider.ConstructorParameters>
            <vm:Dialogs/>
        </ObjectDataProvider.ConstructorParameters>
    </ObjectDataProvider>
</UserControl.Resources>
<StackPanel FlowDirection="RightToLeft" DataContext="{Binding Source={StaticResource LoadImageViewModel}}">
    <Image Source="{Binding Path=ImageSource}" Margin="20 20" Stretch="Fill" Height="200" Width="300"></Image>
    <Button Command="{Binding LoadImageCommand}" Margin="60 20"  Content="Load Image"></Button>
</StackPanel>

于 2013-04-26T23:41:20.203 回答