MovieFinder(MahApp,WPF)
- 누겟 패키지 관리 - CefSharp.Wpf 설치 및 .xaml 수정
- 누겟 패키지 관리 - Google.Apis.Youtube.v3 설치
1) 네이버 영화 버튼 삭제
2) 데이터 그리드 영역 Header 설정
3) TMDB API 이용 영화 클릭 시 포스터 출력
4) 예고편 보기
5) MSSql DB 생성 및 설계
- 서버 탐색기 - 데이터 연결 - 연결 추가
- 6) 프로젝트 구조 재 설계
App.xaml
<Application x:Class="wpf11_MovieFinder.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:wpf11_MovieFinder" StartupUri="MainWindow.xaml"> <Application.Resources> <ResourceDictionary> <ResourceDictionary.MergedDictionaries> <!-- MahApps.Metro resource dictionaries. Make sure that all file names are Case Sensitive! --> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" /> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" /> <!-- Theme setting --> <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Emerald.xaml" /> </ResourceDictionary.MergedDictionaries> </ResourceDictionary> </Application.Resources> </Application>
MainWindow.xaml
<mah:MetroWindow x:Class="wpf11_MovieFinder.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:mah="http://metro.mahapps.com/winfx/xaml/controls" xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks" xmlns:local="clr-namespace:wpf11_MovieFinder" mc:Ignorable="d" Title="moviefinder 2023" Height="450" Width="800" MinHeight="385" MinWidth="645" FontFamily="NanumGothic" Loaded="MetroWindow_Loaded"> <mah:MetroWindow.IconTemplate> <DataTemplate> <iconPacks:PackIconModern Kind="MovieClapper" Foreground="White" Margin="5,7,0,0"/> </DataTemplate> </mah:MetroWindow.IconTemplate> <Grid Margin="10"> <Grid.ColumnDefinitions> <ColumnDefinition Width="2*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="60"/> <RowDefinition Height="1*"/> <RowDefinition Height="80"/> </Grid.RowDefinitions> <!--영화명 검색 부분--> <Grid Grid.Row="0" Grid.Column="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="3*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <!--InputMethod...는 디폴트로 한글 입력 하기 위함--> <TextBox x:Name="TxtMovieName" Grid.Column="0" FontSize="14" Margin="5,10" mah:TextBoxHelper.Watermark="검색할 영화명 입력" mah:TextBoxHelper.UseFloatingWatermark="True" mah:TextBoxHelper.ClearTextButton="True" InputMethod.PreferredImeState="On" InputMethod.PreferredImeConversionMode="Native" KeyDown="TxtMovieName_KeyDown"/> <Button x:Name="BtnSearchMovie" Grid.Column="1" FontSize="14" Margin="5,10" Content="검색" Style="{StaticResource MahApps.Styles.Button.Square.Accent}" Click="BtnSearchMovie_Click"> <Button.ContentTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <iconPacks:PackIconModern Kind="Magnify" Margin="5"/> <TextBlock Text="{Binding}" Margin="5"/> </StackPanel> </DataTemplate> </Button.ContentTemplate> </Button> </Grid> <!--데이터 그리드 영역--> <DataGrid x:Name="GrdResult" Grid.Row="1" Grid.Column="0" Margin="5" IsReadOnly="True" Style="{StaticResource MahApps.Styles.DataGrid.Azure}" ItemsSource="{Binding}" AutoGenerateColumns="False" SelectedCellsChanged="GrdResult_SelectedCellsChanged"> <DataGrid.Columns> <DataGridTextColumn Binding="{Binding Title}" Header="한글명" FontWeight="Bold"/> <DataGridTextColumn Binding="{Binding Original_Title}" Header="원제목"/> <DataGridTextColumn Binding="{Binding Release_Date}" Header="개봉일"/> <DataGridTextColumn Binding="{Binding Popularity,StringFormat={}{0:0.0}}" Header="인기도"> <DataGridTextColumn.ElementStyle> <Style> <Setter Property="TextBlock.TextAlignment" Value="Right"/> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> <DataGridTextColumn Binding="{Binding Vote_Average, StringFormat={}{0:0.0}}" Header="평점"> <DataGridTextColumn.ElementStyle> <Style> <Setter Property="TextBlock.TextAlignment" Value="Right"/> </Style> </DataGridTextColumn.ElementStyle> </DataGridTextColumn> </DataGrid.Columns> </DataGrid> <!--포스터 영역--> <Grid Grid.Row="0" Grid.Column="1" Grid.RowSpan="2"> <GroupBox Header="포스터" Margin="10" mah:HeaderedControlHelper.HeaderFontSize="15" mah:HeaderedControlHelper.HeaderHorizontalContentAlignment="Center" mah:HeaderedControlHelper.HeaderFontFamily="NanumGothic" mah:HeaderedControlHelper.HeaderFontWeight="Bold"> <Image x:Name="ImgPoster" Source="No_Picture.png" Margin="15,5"/> </GroupBox> </Grid> <!--버튼 영역--> <StackPanel Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal"> <Button x:Name="BtnAddFavorite" Content="즐겨찾기 추가" Margin="5,20" FontSize="12" Style="{StaticResource MahApps.Styles.Button.Square.Accent}" Click="BtnAddFavorite_Click"> <Button.ContentTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <iconPacks:PackIconModern Kind="ListAdd" Margin="5"/> <TextBlock Text="{Binding}" Margin="5"/> </StackPanel> </DataTemplate> </Button.ContentTemplate> </Button> <Button x:Name="BtnViewFavorite" Content="즐겨찾기 보기" Margin="5,20" FontSize="12" Style="{StaticResource MahApps.Styles.Button.Square.Accent}"> <Button.ContentTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <iconPacks:PackIconModern Kind="List" Margin="5"/> <TextBlock Text="{Binding}" Margin="5"/> </StackPanel> </DataTemplate> </Button.ContentTemplate> </Button> <Button x:Name="BtnDelFavorite" Content="즐겨찾기 삭제" Margin="5,20" FontSize="12" Style="{StaticResource MahApps.Styles.Button}"> <Button.ContentTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <iconPacks:PackIconModern Kind="ListDelete" Margin="5"/> <TextBlock Text="{Binding}" Margin="5"/> </StackPanel> </DataTemplate> </Button.ContentTemplate> </Button> <Button x:Name="BtnWatchTrailer" Content="예고편 보기" Margin="5,20" FontSize="12" Style="{StaticResource MahApps.Styles.Button.Flat}" Click="BtnWatchTrailer_Click"> <Button.ContentTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <iconPacks:PackIconModern Kind="YoutubePlay" Margin="5"/> <TextBlock Text="{Binding}" Margin="5"/> </StackPanel> </DataTemplate> </Button.ContentTemplate> </Button> <!--<Button x:Name="BtnNaverMovie" Content="네이버 영화" Foreground="#099A49" Margin="5,20" FontSize="12" Click="BtnNaverMovie_Click" Style="{StaticResource MahApps.Styles.Button}"> <Button.ContentTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <Image Source="naver.png" Width="20"/> <TextBlock Text="{Binding}" Margin="5"/> </StackPanel> </DataTemplate> </Button.ContentTemplate> </Button>--> </StackPanel> </Grid> </mah:MetroWindow>
- 영화명 검색 / 데이터 그리드 영역 / 포스터 영역 / 버튼 영역 구분하여 구현
MainWindow.xaml.cs
using MahApps.Metro.Controls; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.Data.SqlClient; using System.Diagnostics; using System.IO; using System.Net; using System.Text; using System.Web; using System.Windows; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media.Imaging; using wpf11_MovieFinder.Logics; using wpf11_MovieFinder.Models; namespace wpf11_MovieFinder { /// <summary> /// MainWindow.xaml에 대한 상호 작용 논리 /// </summary> public partial class MainWindow : MetroWindow { bool isFavorite = false; // false->openApi 검색해온 결과, true-> 즐겨찾기 보기 클릭 public MainWindow() { InitializeComponent(); } private async void BtnNaverMovie_Click(object sender, RoutedEventArgs e) { await Commons.ShowMessageAsync("네이버 영화", "네이버 영화 사이트로 이동합니다!"); } //네이버 API 사용 네이버 영화 검색 버튼 private async void BtnSearchMovie_Click(object sender, RoutedEventArgs e) { if(string.IsNullOrEmpty(TxtMovieName.Text)) { await Commons.ShowMessageAsync("검색", "검색할 영화명을 입력하세요."); return; } //if(TxtMovieName.Text.Length<=1)//두글자는 써줘라 //{ // await Commons.ShowMessageAsync("검색", "검색어를 2자이상 입력하세요."); // return; //} try {// 실제 검색 메서드 SearchMovie(TxtMovieName.Text); } catch(Exception ex) { await Commons.ShowMessageAsync("오류", $"오류 발생 : {ex.Message}"); } } //textBox에서 엔터 누를 시 검색 private void TxtMovieName_KeyDown(object sender, KeyEventArgs e) { if(e.Key==Key.Enter) { BtnSearchMovie_Click(sender, e); } } //실제 검색 메서드 private async void SearchMovie(string movieName) { string tmdb_apiKey = "dd21bad55619f84e6e2823be028cbba2"; string encoding_movieName = HttpUtility.UrlEncode(movieName, Encoding.UTF8); string openApiUri = $@"https://api.themoviedb.org/3/search/movie?api_key={tmdb_apiKey}&language=ko-KR&page=1&include_adult=false&query={encoding_movieName}"; string result = string.Empty; //결과값 //api 실행할 객체 WebRequest req = null; WebResponse res = null; StreamReader reader = null; // TMDB API 요청 try { req = WebRequest.Create(openApiUri);//URL을 넣어 객체 생성 //Naver Api 헤더 설정 res = await req.GetResponseAsync(); //요청한 결과를 응답에 할당 reader = new StreamReader(res.GetResponseStream()); result = reader.ReadToEnd();//json 결과 텍스트로 저장 Debug.WriteLine(result); } catch (Exception ex) { throw ex; } finally { reader.Close(); res.Close(); } //result를 json으로 변경 var jsonResult=JObject.Parse(result); var total = Convert.ToInt32(jsonResult["total_results"]);//전체 검색 결과 수 var items = jsonResult["results"]; //items를 데이터 그리드에 표시 var json_array = items as JArray; var movieItems = new List<MovieItem>();//json에서 넘어온 배열을 담을 장소 foreach(var val in json_array) { var MovieItem = new MovieItem() { Adult = Convert.ToBoolean(val["adult"]), Id = Convert.ToInt32(val["id"]), Original_Language = Convert.ToString(val["original_language"]), Original_Title = Convert.ToString(val["original_title"]), Overview = Convert.ToString(val["overview"]), Popularity = Convert.ToDouble(val["popularity"]), Poster_Path = Convert.ToString(val["poster_path"]), Release_Date = Convert.ToString(val["release_date"]), Title = Convert.ToString(val["title"]), Vote_Average = Convert.ToDouble(val["vote_average"]) }; movieItems.Add(MovieItem); } this.DataContext=movieItems; } private void MetroWindow_Loaded(object sender, RoutedEventArgs e) { TxtMovieName.Focus(); } private void GrdResult_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e) { try { // 그리드에서 셀 선택 시 이벤트 var movie = GrdResult.SelectedItem as MovieItem; //Debug.WriteLine(movie.Poster_Path); if (string.IsNullOrEmpty(movie.Poster_Path))//포스터 이미지 없으면 No_Picture 출력 { ImgPoster.Source = new BitmapImage(new Uri("/No_Picture.png", UriKind.RelativeOrAbsolute)); } else//포스터 이미지 경로가 있으면 { var base_url = "https://image.tmdb.org/t/p/w300_and_h450_bestv2"; ImgPoster.Source = new BitmapImage(new Uri($"{base_url}{movie.Poster_Path}", UriKind.RelativeOrAbsolute)); } } catch { } } private async void BtnWatchTrailer_Click(object sender, RoutedEventArgs e) { // 영화 예고편 Youtube에서 보기 if(GrdResult.SelectedItems.Count==0) { await Commons.ShowMessageAsync("Youtube", "영화를 선택해주세요!"); return; } if(GrdResult.SelectedItems.Count>1) { await Commons.ShowMessageAsync("Youtube", "영화를 하나만 선택해주세요!"); return; } string movieName = string.Empty; var movie = GrdResult.SelectedItem as MovieItem; //영화의 모든 정보 movieName = movie.Title; //await Commons.ShowMessageAsync("유튜브", $"예고편 볼 영화 : {movieName}"); var trailerWindow = new TrailerWindow(movieName); trailerWindow.Owner = this;//trailerwindow의 부모는 MainWindow trailerWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;//부모창 중앙에 위치 trailerWindow.ShowDialog();//모달창으로 열기. show()로 모달리스로 열면 부모창 건드려짐 } //즐겨찾기 저장 private async void BtnAddFavorite_Click(object sender, RoutedEventArgs e) { if(GrdResult.SelectedItems.Count==0) { await Commons.ShowMessageAsync("오류", "즐겨찾기에 추가할 영화를 선택하세요(복수선택 가능)"); return; } if(isFavorite) { await Commons.ShowMessageAsync("오류", "이미 즐겨찾기한 영화입니다"); return; } List<FavoriteMovieItem> list = new List<FavoriteMovieItem>(); foreach(MovieItem item in GrdResult.SelectedItems) { var favoriteMovie = new FavoriteMovieItem { Id = item.Id, Title = item.Title, Original_Title = item.Original_Title, Adult = item.Adult, Overview = item.Overview, Release_Date = item.Release_Date, Original_Language = item.Original_Language, Vote_Average = item.Vote_Average, Popularity = item.Popularity, Poster_Path = item.Poster_Path, Reg_Date = DateTime.Now // 지금 저장하는 일시 생성 }; list.Add(favoriteMovie); } try { // DB 연결 확인 using (SqlConnection conn = new SqlConnection(Commons.connString)) { if (conn.State == System.Data.ConnectionState.Closed) conn.Open(); var query = @"INSERT INTO [dbo].[FavoriteMovieItem] ([id] ,[Title] ,[Original_Title] ,[Realease_Date] ,[Original_Language] ,[Adult] ,[Popularity] ,[Vote_Average] ,[Poster_Path] ,[Overview] ,[Reg_Date]) VALUES (@id ,@Title ,@Original_Title ,@Realease_Date ,@Original_Language ,@Adult ,@Popularity ,@Vote_Average ,@Poster_Path ,@Overview ,@Reg_Date)"; var insRes = 0; foreach(FavoriteMovieItem item in list) { SqlCommand cmd = new SqlCommand(query, conn); cmd.Parameters.AddWithValue("@id", item.Id); cmd.Parameters.AddWithValue("@Title", item.Title); cmd.Parameters.AddWithValue("@Original_Title", item.Original_Title); cmd.Parameters.AddWithValue("@Realease_Date", item.Release_Date); cmd.Parameters.AddWithValue("@Original_Language", item.Original_Language); cmd.Parameters.AddWithValue("@Adult", item.Adult); cmd.Parameters.AddWithValue("@Popularity", item.Popularity); cmd.Parameters.AddWithValue("@Vote_Average", item.Vote_Average); cmd.Parameters.AddWithValue("@Poster_Path", item.Poster_Path); cmd.Parameters.AddWithValue("@Overview", item.Overview); cmd.Parameters.AddWithValue("@Reg_Date", item.Reg_Date); insRes+=cmd.ExecuteNonQuery(); } if(list.Count == insRes) { await Commons.ShowMessageAsync("저장", "DB 저장 성공"); } else { await Commons.ShowMessageAsync("저장", "DB 저장 오류 관리자에게 문의하세요!"); } } } catch(Exception ex) { await Commons.ShowMessageAsync("오류", $"DB저장 오류 {ex.Message}"); } } } }
- 포스터 뿌려주기 및 DB 연결
TrailerWindow.xaml
<mah:MetroWindow x:Class="wpf11_MovieFinder.TrailerWindow" 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:mah="http://metro.mahapps.com/winfx/xaml/controls" xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks" xmlns:cefSharp ="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf" xmlns:local="clr-namespace:wpf11_MovieFinder" mc:Ignorable="d" Title="유튜브 예고편" Height="350" Width="800" FontFamily="NanumGothic" Loaded="MetroWindow_Loaded" Closing="MetroWindow_Closing"> <mah:MetroWindow.IconTemplate> <DataTemplate> <iconPacks:PackIconModern Kind="Youtube" Foreground="White" Margin="5,7,0,0"/> </DataTemplate> </mah:MetroWindow.IconTemplate> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="1*"/> <ColumnDefinition Width="1*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="50"/> <RowDefinition Height="1*"/> </Grid.RowDefinitions> <Label Grid.Row="0" Grid.Column="0" x:Name="LblMovieName" FontSize="14" Margin="10" Content="영화제목"/> <ListView Grid.Row="1" Grid.Column="0" x:Name="LsvResult" Margin="5" MouseDoubleClick="LsvResult_MouseDoubleClick"> <ListView.View> <GridView> <!--컬럼들 나열--> <GridViewColumn Header="썸네일" Width="100"> <GridViewColumn.CellTemplate> <DataTemplate> <Image Source="{Binding Thumbnail}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn Header="타이틀" Width="Auto" DisplayMemberBinding="{Binding Title}"/> <!--<GridViewColumn Header="제작자" Width="Auto" DisplayMemberBinding="{Binding Author}"/>--> <GridViewColumn Header="채널명" Width="Auto" DisplayMemberBinding="{Binding ChannelTitle}"/> <GridViewColumn Header="링크" Width="Auto" DisplayMemberBinding="{Binding URL}"/> </GridView> </ListView.View> </ListView> <!--웹브라우저 영역--> <Grid Grid.Row="0" Grid.Column="1" Grid.RowSpan="2" Margin="10" Background="Gainsboro"> <cefSharp:ChromiumWebBrowser x:Name="BrsYoutube" Address="https://www.youtube.com"/> </Grid> </Grid> </mah:MetroWindow>
TrailerWindow.xaml.cs
using Google.Apis.Services; using Google.Apis.YouTube.v3; using MahApps.Metro.Controls; using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Shapes; using wpf11_MovieFinder.Models; namespace wpf11_MovieFinder { /// <summary> /// TrailerWindow.xaml에 대한 상호 작용 논리 /// </summary> public partial class TrailerWindow : MetroWindow { List<YoutubeItem> youtubeItems = null; // 검색결과를 담을 리스트 public TrailerWindow() { InitializeComponent(); } //부모에서 데이터를 가져오려면 반드시 필요한 재정의 생성자 public TrailerWindow(string movieName) : this() { LblMovieName.Content = $"{movieName} 예고편"; } private void MetroWindow_Loaded(object sender, RoutedEventArgs e) { //화면 로드 완료 후 Youtube 실행 youtubeItems = new List<YoutubeItem>();//초기화 SearchYoutubeApi(); } private async void SearchYoutubeApi() { await LoadDataCollection(); LsvResult.ItemsSource = youtubeItems; // direct binding } private async Task LoadDataCollection() { var youtubeService = new YouTubeService( new BaseClientService.Initializer() { ApiKey = "AIzaSyCRs0FAqizh_j_LMqren845f3Bwrs4Nhk8",//구글에서 발급받은 youtube api key ApplicationName = this.GetType().ToString() }); var req = youtubeService.Search.List("snippet"); req.Q = LblMovieName.Content.ToString(); req.MaxResults = 10; var res = await req.ExecuteAsync(); //검색 결과를 받아옴 Debug.WriteLine("유튜브 검색결과 ---"); foreach (var item in res.Items) { Debug.WriteLine(item.Snippet.Title); if(item.Id.Kind.Equals("youtube#video"))//youtube#video만 플레이 { YoutubeItem youtube = new YoutubeItem { Title = item.Snippet.Title, ChannelTitle = item.Snippet.ChannelTitle, URL = $"https://www.youtube.com/watch?v={item.Id.VideoId}" , //유튜브 플레이 링크 //Author = item.Snippet.ChannelTitle }; youtube.Thumbnail = new BitmapImage(new Uri(item.Snippet.Thumbnails.Default__.Url, UriKind.RelativeOrAbsolute)); youtubeItems.Add(youtube); } } } private void LsvResult_MouseDoubleClick(object sender, MouseButtonEventArgs e) { if(LsvResult.SelectedItem is YoutubeItem) { var video = LsvResult.SelectedItem as YoutubeItem; BrsYoutube.Address = video.URL; } } private void MetroWindow_Closing(object sender, System.ComponentModel.CancelEventArgs e) { BrsYoutube.Address = string.Empty;//웹브라우저 주소 클리어 BrsYoutube.Dispose();//리소스 해제 } //부모에서 영화 객체를 통째로 전달 //public TrailerWindow(MovieItem movie):this() //{ // LblMovieName.Content= $"{movie} 예고편"; //} } }
Logics/Commons.cs
using MahApps.Metro.Controls; using MahApps.Metro.Controls.Dialogs; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; namespace wpf11_MovieFinder.Logics { public class Commons { // 연결 문자열 담을 변수 public static readonly string connString = "Data Source=localhost;" + "Initial Catalog=pknu;" + "Persist Security Info=True;"+ "User ID=sa;"+ "Password=12345"; //매트로 다이얼로그창을 위한 정적 메서드 public static async Task<MessageDialogResult> ShowMessageAsync(string title, string message, MessageDialogStyle style = MessageDialogStyle.Affirmative) { return await ((MetroWindow)Application.Current.MainWindow).ShowMessageAsync(title, message, style, null); } } }
- connString은 연결 후 우측 솔루션 탐색기 하단에 나오는 속성 / 문자열을 참조할것
Models/FavoriteMovieItem.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace wpf11_MovieFinder.Models { public class FavoriteMovieItem { public bool Adult { get; set; } public int Id { get; set; } public string Original_Language { get; set; } public string Original_Title { get; set; } public string Overview { get; set; } public double Popularity { get; set; } public string Poster_Path { get; set; } public string Release_Date { get; set; } public string Title { get; set; } public double Vote_Average { get; set; } public DateTime Reg_Date { get; set; } } }
Models/MovieItem.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace wpf11_MovieFinder.Models { public class MovieItem { public bool Adult { get; set; } public int Id { get; set; } public string Original_Language { get; set; } public string Original_Title { get; set;} public string Overview { get; set; } public double Popularity { get; set; } public string Poster_Path { get; set; } public string Release_Date { get; set; } public string Title { get; set; } public double Vote_Average { get; set; } } }
Models/YoutubeItem.cs
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Media.Imaging; namespace wpf11_MovieFinder.Models { public class YoutubeItem { public string Title { get; set; } public string Author { get; set; } public string ChannelTitle { get; set; } public string URL { get; set; } public BitmapImage Thumbnail { get; set; } } }
실행화면
Main 화면
영화 검색 후 데이터 그리드에서 영화 클릭
예고편 보기 Button 클릭
예고편 더블 클릭
--> 우측에 해당 예고편 재생
즐겨찾기 추가
--> SSMS의 FavoriteMovieItem DB에 선택하여 즐겨찾기에 추가한 영화인 존윅 4 삽입됨을 확인