为什么不显示图像?是我的代码错了吗?
视图中的xaml代码:
<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>
ViewModel代码:
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));
}
}
}
答案 0 :(得分:3)
这一行
_imageSource = decoder.Frames[0];
LoadImage
方法中的是错误的。
您需要设置属性ImageSource
,以便提升属性的PropertyChanged
- 事件。
将其更改为
ImageSource = decoder.Frames[0];
答案 1 :(得分:0)
我认为这是更合适的代码:
ViewModel代码:
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>