환경 :
Window10, Visual Studio 2019, WPF, MVVMLight, OpencvSharp
usercontrol 폴더
ImageViewer.xaml
<UserControl x:Class="WpfApp1.usercontrol.ImageViewer"
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:local="clr-namespace:WpfApp1.usercontrol"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Image x:Name="image"/>
</Grid>
</UserControl>
ImageViewer.xaml.cs
using OpenCvSharp;
using System.Windows;
using System.Windows.Controls;
using WpfApp1.utility;
namespace WpfApp1.usercontrol
{
/// <summary>
/// ImageViewer.xaml에 대한 상호 작용 논리
/// </summary>
public partial class ImageViewer : UserControl
{
public ImageViewer()
{
InitializeComponent();
}
public Mat MatImage
{
get { return (Mat)GetValue(MyProperty); }
set { SetValue(MyProperty, value); }
}
public static readonly DependencyProperty MyProperty =
DependencyProperty.Register(
"MatImage",
typeof(Mat),
typeof(ImageViewer),
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnMyPropertyChanged)));
private static void OnMyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ImageViewer viewer = d as ImageViewer;
viewer.image.Source = ImageHandler.IplImageToInteropBitmap((e.NewValue as Mat));
}
}
}
주요코드
1. MatImage의 GetValue,SetValue
2. MyProperty의 등록 과정
DependecyProperty.Register(
"MatImage", // 실제 xaml에 노출 시킬 변수 명 추 후 Binding 시킨다.
typeof(Mat), // 위의 MatImage의 타입을 정의한다.
typeof(ImageViewer), // MatImage 변수를 가지고 있는 객체 타입을 정의한다.
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnMyPropertyChanged)));
//OnMyPropertyChanged 함수로 콜백을 등록한다.
3. OnMyPropertyChanged 함수
DependecyObject - MatImage 인스턴스를 가지고 있는 오너 인스턴스 타입으로 사용.
DependencyPropertyChangedEventArgs - 외부 Binding을 통해 전달된 Mat Type의 인스턴스.
private static void OnMyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ImageViewer viewer = d as ImageViewer; // 오너 인스턴스로 변환
//e.NewValue as Mat으로 외부에서 바인딩한 데이터 변환
viewer.image.Source = ImageHandler.IplImageToInteropBitmap((e.NewValue as Mat));
}
ViewModel 폴더
MainViewModel.cs
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Win32;
using OpenCvSharp;
using WpfApp1.utility;
namespace WpfApp1.ViewModel
{
/// <summary>
/// This class contains properties that the main View can data bind to.
/// <para>
/// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
/// </para>
/// <para>
/// You can also use Blend to data bind with the tool's support.
/// </para>
/// <para>
/// See http://www.galasoft.ch/mvvm
/// </para>
/// </summary>
public class MainViewModel : ViewModelBase
{
Mat _matImage;
public Mat matImage
{
get
{
return _matImage;
}
set
{
_matImage = value;
RaisePropertyChanged(() => matImage);
}
}
public RelayCommand OpenImage { get; set; }
public MainViewModel()
{
OpenImage = new RelayCommand(OpenImageAction);
}
void OpenImageAction()
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.RestoreDirectory = true;
openFileDialog.DefaultExt = "jpg";
openFileDialog.Filter = "Images Files(*.jpg; *.bmp; *.png)|*.jpg;*.bmp;*.png";
if (openFileDialog.ShowDialog() == true)
{
//Get the path of specified file
string strImagePath = openFileDialog.FileName;
matImage = ImageHandler.OpenImage(strImagePath);
}
}
}
}
주요 코드
1. matImage 프로퍼티를 이용한 바인딩 코드
Mat _matImage;
public Mat matImage
{
get
{
return _matImage;
}
set
{
_matImage = value;
RaisePropertyChanged(() => matImage);
}
}
MainWindow.xaml
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
xmlns:uc="clr-namespace:WpfApp1.usercontrol"
mc:Ignorable="d"
DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<uc:ImageViewer MatImage="{Binding matImage}" Grid.Column="0"/>
<Button Command="{Binding OpenImage}" Grid.Column="1"/>
</Grid>
</Window>
주요코드
ImageViewer에서 등록한 MatImage를 MainViewModel의 matImage 프로퍼티에 바인딩.
<uc:ImageViewer MatImage="{Binding matImage}" Grid.Column="0"/>
결과