I am new to WPF and C#, I try to implement an Image control, which is updated whenever there is new data coming from serial port, but failed after a lot of attempts. It just shows the black image at the beginning and when there is new data coming, the Image control is not updated (ImageSource in ImageViewModel was not updated and event NotifyPropertyChanged was not fired). Can anyone help me out?
I have 3 classes and 1 Usercontrol. They are ImageViewModel, ImageConverter, Control and UserControl and UserControl code behind.
My ImageViewModel class
public class ImageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private System.Drawing.Image _img;
public System.Drawing.Image ImageSource
{
get { return _img; }
set { _img = value; NotifyPropertyChanged("ImageSource"); }
}
public ImageViewModel()
{
ImageSource = new System.Drawing.Bitmap(320, 240);
}
}
My ImageConverter Class
[ValueConversion(typeof(System.Drawing.Image), typeof(System.Windows.Media.ImageSource))]
public class ImageConverter : IValueConverter
{
public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
// empty images are empty...
if (value == null) { return null; }
else
{
var image = (System.Drawing.Image)value;
// Winforms Image we want to get the WPF Image from...
var bitmap = new System.Windows.Media.Imaging.BitmapImage();
bitmap.BeginInit();
MemoryStream memoryStream = new MemoryStream();
// Save to a memory stream...
image.Save(memoryStream, ImageFormat.Bmp);
// Rewind the stream...
memoryStream.Seek(0, System.IO.SeekOrigin.Begin);
bitmap.StreamSource = memoryStream;
bitmap.EndInit();
return bitmap;
}
}
public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
My Control class
public void OpenPort()
{
try
{
SerialPort.Open();
SerialPort.DataReceived += new SerialDataReceivedEventHandler(receivedDataFromSerialPort);
SerialPort.DtrEnable = true;
SerialPort.RtsEnable = true;
}
catch (Exception e)
{
throw e;
}
}
public void ClosePort()
{
try
{
SerialPort.Close();
SerialPort.DataReceived -= new SerialDataReceivedEventHandler(receivedDataFromSerialPort);
}
catch (Exception ex)
{
throw ex;
}
}
ImageViewModel ivm = new ImageViewModel();
private void receivedDataFromSerialPort(object sender, SerialDataReceivedEventArgs e)
{
System.Drawing.Image tmp = new Bitmap(320,240);
//other codes
ivm.ImageSource = tmp;
}
My Usercontrol
<UserControl.Resources>
<imgcv:ImageConverter x:Key="imageConverter" />
</UserControl.Resources>
<UserControl.DataContext>
<viewmodel:ImageViewModel/>
</UserControl.DataContext>
<StackPanel Height="240" Width="300">
<Image Width="320" Height="240" Source="{Binding Path=ImageSource,IsAsync=True, Converter={StaticResource imageConverter},ConverterParameter=ImageSource, UpdateSourceTrigger=LostFocus}" />
</StackPanel>
UserControl code behind
public partial class UserControls : System.Windows.Controls.UserControl
{
Control ctrl = new Control();
//other codes
ctrl.OpenPort();
//other codes
ctrl.ClosePort();
}
Thanks a lot!