※ 네이버 영화 사라짐
Naver Developer
[pw : sujin4792@]
<Application x:Class="wp11_MovieFinder.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:wp11_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>
<mah:MetroWindow
x:Class="wp11_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:wp11_MovieFinder"
mc:Ignorable="d"
Title="MovieFinder 2023" Height="450" Width="800" MinHeight="385" MinWidth="645"
FontFamily="NanumGothic" WindowStartupLocation="CenterScreen" Loaded="MetroWindow_Loaded">
<mah:MetroWindow.IconTemplate>
<DataTemplate>
<iconPacks:PackIconModern Kind="Film" 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"/>
<RowDefinition Height="1"/>
</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 Grid.Row="1" Grid.Column="0" x:Name="GrdResult" 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="TITLE" />
<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>
<!--<DataGridCheckBoxColumn Binding="{Binding Adult}" Header="성인물" />-->
</DataGrid.Columns>
</DataGrid>
<!--포스터 영역-->
<Grid Grid.Row="0" Grid.Column="1" Grid.RowSpan="2">
<GroupBox Header="포스터" Margin="5"
mah:HeaderedControlHelper.HeaderFontSize="14"
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>
<!--#region버튼-->
<StackPanel Grid.Column="0" Grid.Row="2" 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,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.Highlight}" Click="BtnViewFavorite_Click">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconModern Kind="List" Margin="5,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.Square}" Click="BtnDelFavorite_Click">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconModern Kind="ListDelete" Margin="5,5" Foreground="#099A46"/>
<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,5" Foreground="#E7161B"/>
<TextBlock Text="{Binding}" Margin="5"/>
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
<!--<Button x:Name="BtnNaverMovie" Content="네이버 영화" Margin="5,20" FontSize="12"
Style="{StaticResource MahApps.Styles.Button.Flat}" Click="BtnNaverMovie_Click">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="Naverlogo.png" Width="15" Margin="5,5"/>
<TextBlock Text="{Binding}" Margin="5"/>
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>-->
</StackPanel>
<!--#endregion-->
<!--상태표시바-->
<StatusBar Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Margin="-10">
<StatusBarItem Content="TMDB & Youtube OpenAPI App"/>
<Separator Style="{StaticResource MahApps.Styles.Separator.StatusBar}"/>
<StatusBarItem x:Name="StsResult"/>
</StatusBar>
</Grid>
</mah:MetroWindow>
using ControlzEx.Standard;
using MahApps.Metro.Controls;
using MySql.Data.MySqlClient;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Web;
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.Navigation;
using System.Windows.Shapes;
using wp11_MovieFinder.Logics;
using wp11_MovieFinder.Models;
namespace wp11_MovieFinder
{
/// <summary>
/// MainWindow.xaml에 대한 상호 작용 논리
/// </summary>
public partial class MainWindow : MetroWindow
{
bool isFavorite = false; // false ->
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 < 2)
//{
// await Commons.ShowMessageAsync("검색", "검색어를 두글자 이상 입력하세요.");
// return;
//}
try
{
SearchMovie(TxtMovieName.Text);
}
catch (Exception ex)
{
await Commons.ShowMessageAsync("오류", $"오류발생 : {ex.Message}");
}
}
// 텍스트박스에서 키를 입력할때 엔터를 누르면 검색 시작
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 = "fd2b7822a5956759efbe476287b3a0c0";
string encording_movieName = HttpUtility.UrlDecode(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={encording_movieName}";
string result = string.Empty; //결과값
//api 실행할 객체
WebRequest req = null;
WebResponse res = null;
StreamReader reader = null;
// TMDB API 요청
try
{
req = WebRequest.Create(openApiUri); // Url을 넣어서 객체를 생성
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); // string -> json
var total = Convert.ToInt32(jsonResult["total_results"]); //전체 검색결과 수
//await Commons.ShowMessageAsync("검색결과", total.ToString());
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;
isFavorite = false; //즐겨찾기 아님
StsResult.Content = $"OpenAPI {movieItems.Count}건 조회완료";
}
private void MetroWindow_Loaded(object sender, RoutedEventArgs e)
{
TxtMovieName.Focus(); // 텍스트 박스에 포커스 set
}
// 그리드에서 셀을 선택하면 발생하는 이벤트 핸들러
private async void GrdResult_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
{
try
{
string posterPath = string.Empty;
if(GrdResult.SelectedItem is MovieItem) // OpenAPI로 검색된 영화의 포스터
{
var movie = GrdResult.SelectedItem as MovieItem;
posterPath = movie.Poster_Path;
}
else if(GrdResult.SelectedItem is FavoriteMovieItem) // 즐겨찾기 DB에서 가져온 영화 포스터
{
var movie = GrdResult.SelectedItem as FavoriteMovieItem;
posterPath = movie.Poster_Path;
}
Debug.WriteLine(posterPath);
if(string.IsNullOrEmpty(posterPath)) // 포스터 이미지가 없다면 => No_Picture 나오게
{
ImgPoster.Source = new BitmapImage(new Uri("/No_Picture.png", UriKind.RelativeOrAbsolute));
}
else // 포스터 이미지 경로가 존재한다면
{
var base_url = "https://www.themoviedb.org/t/p/w600_and_h900_bestv2";
ImgPoster.Source = new BitmapImage(new Uri($"{base_url}{posterPath}", UriKind.RelativeOrAbsolute));
}
}
catch
{
await Commons.ShowMessageAsync("오류", $"이미지로드 오류발생");
}
}
// 영화 예고편 유튜브에서 보기
private async void BtnWatchTrailer_Click(object sender, RoutedEventArgs e)
{
if(GrdResult.SelectedItems.Count == 0)
{
await Commons.ShowMessageAsync("유튜브", "영화를 선택하세요.");
return;
}
if(GrdResult.SelectedItems.Count > 1)
{
await Commons.ShowMessageAsync("유튜브", "영화를 하나만 선택하세요.");
return;
}
string movieName = string.Empty;
// 전체 넘기는 코드 가져오기
if(GrdResult.SelectedItem is MovieItem)
{
var movie = GrdResult.SelectedItem as MovieItem;
movieName = movie.Title;
}
else if(GrdResult.SelectedItem is FavoriteMovieItem)
{
var movie = GrdResult.SelectedItem as FavoriteMovieItem;
movieName = movie.Title;
}
//movieName = (GrdResult.SelectedItem as MovieItem).Title;
//await Commons.ShowMessageAsync("유튜브", $"예고편 볼 영화 {movieName}");
var trailerWindow = new TrailerWindow(movieName);
trailerWindow.Owner = this; //TrailerWindow의 부모는 MainWindow
trailerWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner; // 부모창의 정중앙에 위치
//trailerWindow.Show(); // 모달리스로 창을 열면 부모창 접근 가능
trailerWindow.ShowDialog(); // 모달창
}
//즐겨찾기 추가
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,
Original_Language = item.Original_Language,
Adult = item.Adult,
Overview = item.Overview,
Release_Date = item.Release_Date,
Vote_Average = item.Vote_Average,
Popularity = item.Popularity,
Poster_Path = item.Poster_Path,
Reg_Date = DateTime.Now // 지금 저장하는 일시
};
list.Add(favoriteMovie);
}*/
#region < MySQL DB 데이터 입력(Test)>
/*try
{
// DB
using (MySqlConnection conn = new MySqlConnection(Commons.myConnString))
{
if (conn.State == ConnectionState.Closed) conn.Open();
var query = @"INSERT INTO FavoriteMovieItem
( Id
, Title
, Original_Title
, Release_Date
, Original_Language
, Adult
, Popularity
, Vote_Average
, Poster_Path
, Overview
, Reg_Date )
VALUES
( @Id
, @Title
, @Original_Title
, @Release_Date
, @Original_Language
, @Adult
, @Popularity
, @Vote_Average
, @Poster_Path
, @Overview
, @Reg_Date )";
var insRes = 0;
foreach (FavoriteMovieItem item in list)
{
MySqlCommand cmd = new MySqlCommand(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("@Release_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();
}
}
}
catch (Exception ex)
{
await Commons.ShowMessageAsync("오류", $"DB저장 오류 {ex.Message}");
}*/
#endregion
#region < SQL Server DB 데이터 입력>
try
{
// DB
using (SqlConnection conn = new SqlConnection(Commons.connString))
{
if(conn.State == ConnectionState.Closed) conn.Open();
var query = @"INSERT INTO [dbo].[FavoriteMovieItem]
( [Id]
, [Title]
, [Original_Title]
, [Release_Date]
, [Original_Language]
, [Adult]
, [Popularity]
, [Vote_Average]
, [Poster_Path]
, [Overview]
, [Reg_Date] )
VALUES
( @Id
, @Title
, @Original_Title
, @Release_Date
, @Original_Language
, @Adult
, @Popularity
, @Vote_Average
, @Poster_Path
, @Overview
, @Reg_Date )";
var insRes = 0;
foreach (MovieItem item in GrdResult.SelectedItems) // OpenAPI로 검색된 결과라서 MovieItem
{
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("@Release_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", DateTime.Now);
insRes += cmd.ExecuteNonQuery();
}
if(GrdResult.SelectedItems.Count == insRes)
{
await Commons.ShowMessageAsync("저장", "즐겨찾기 추가 성공");
StsResult.Content = $"즐겨찾기 {insRes}건 저장완료";
}
else
{
await Commons.ShowMessageAsync("저장", "즐겨찾기 추가 실패! 관리자에게 문의하세요.");
}
}
}
catch (Exception ex)
{
await Commons.ShowMessageAsync("오류",$"DB저장 오류 {ex.Message}");
}
#endregion
}
// 즐겨찾기 보기
private async void BtnViewFavorite_Click(object sender, RoutedEventArgs e)
{
this.DataContext = null;
TxtMovieName.Text = string.Empty;
List<FavoriteMovieItem> list = new List<FavoriteMovieItem>();
try
{
using (SqlConnection conn = new SqlConnection(Commons.connString))
{
if(conn.State == ConnectionState.Closed) conn.Open();
var query = @"SELECT Id
,Title
,Original_Title
,Release_Date
,Original_Language
,Adult
,Popularity
,Vote_Average
,Poster_Path
,Overview
,Reg_Date
FROM FavoriteMovieItem
ORDER BY Id ASC";
var cmd = new SqlCommand(query, conn);
var adapter = new SqlDataAdapter(cmd);
var dSet = new DataSet();
adapter.Fill(dSet, "FavoriteMovieItem");
foreach (DataRow dr in dSet.Tables["FavoriteMovieItem"].Rows) {
list.Add(new FavoriteMovieItem
{
Id = Convert.ToInt32(dr["id"]),
Title = Convert.ToString(dr["title"]),
Original_Title = Convert.ToString(dr["Original_Title"]),
Release_Date = Convert.ToString(dr["Release_Date"]),
Original_Language = Convert.ToString(dr["Original_Language"]),
Adult = Convert.ToBoolean(dr["Adult"]),
Popularity = Convert.ToDouble(dr["Popularity"]),
Vote_Average = Convert.ToDouble(dr["Vote_Average"]),
Poster_Path = Convert.ToString(dr["Poster_Path"]),
Overview = Convert.ToString(dr["Poster_Path"]),
Reg_Date = Convert.ToDateTime(dr["Reg_Date"])
});
}
this.DataContext = list;
isFavorite = true;
StsResult.Content = $"즐겨찾기 {list.Count}건 조회완료";
}
}
catch (Exception ex)
{
await Commons.ShowMessageAsync("오류", $"DB조회 오류 {ex.Message}");
}
}
// 즐겨찾기 삭제
private async void BtnDelFavorite_Click(object sender, RoutedEventArgs e)
{
if(isFavorite == false)
{
await Commons.ShowMessageAsync("오류", "즐겨찾기만 삭제할 수 있습니다.");
return;
}
if(GrdResult.SelectedItems.Count == 0)
{
await Commons.ShowMessageAsync("오류", "삭제할 영화를 선택하세요");
return;
}
try // 삭제
{
using (SqlConnection conn = new SqlConnection(Commons.connString))
{
if (conn.State == ConnectionState.Closed) conn.Open();
var query = "DELETE FROM FavoriteMovieItem WHERE Id = @Id";
var delRes = 0;
foreach (FavoriteMovieItem item in GrdResult.SelectedItems)
{
SqlCommand cmd = new SqlCommand(query, conn);
cmd.Parameters.AddWithValue("@Id", item.Id);
delRes += cmd.ExecuteNonQuery();
}
if(delRes == GrdResult.SelectedItems.Count)
{
await Commons.ShowMessageAsync("삭제", "DB삭제 성공!");
BtnViewFavorite_Click(sender, e); //즐겨찾기 보기 이벤트 핸들러 한 번 실행
StsResult.Content = $"즐겨찾기 {delRes}건 삭제완료"; // 바로 즐겨찾기 조회창이 뜨기 때문에 화면에서 볼 수 없다
}
else
{
await Commons.ShowMessageAsync("삭제", "DB삭제 일부 성공"); //발생 가능성 낮음
}
}
}
catch (Exception ex)
{
await Commons.ShowMessageAsync("오류",$"DB삭제오류 {ex.Message}");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace wp11_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; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace wp11_MovieFinder.Models
{
internal 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; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
namespace wp11_MovieFinder.Models
{
internal class YoutubeItem
{
public string Title { get; set; }
public string Author { get; set; }
public string URL { get; set; }
public string ChannelTitle { get; set; }
public BitmapImage Thumbnail { get; set; }
}
}
using Google.Protobuf.WellKnownTypes;
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 wp11_MovieFinder.Logics
{
public class Commons
{
// 연결문자열 담을 변수
// SQL Server용
public static readonly string connString = "Data Source=localhost;" +
"Initial Catalog=pknu;" +
"Persist Security Info=True;" +
"User ID=sa;" +
"Password=12345";
// MySQL용
public static readonly string myConnString = "Server=localhost;" +
"Port=3306;" +
"Database=miniproject;" +
"Uid=root;" +
"Pwd=815301;";
// 매트로 다이얼로그창을 위한 정적 메서드
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);
}
}
}
<mah:MetroWindow
x:Class="wp11_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:wp11_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"/>
<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="LightGray">
<!--<WebBrowser/> 문제 많음-->
<cefSharp:ChromiumWebBrowser x:Name="BrsYoutube" Address="https://www.youtube.com"/>
</Grid>
</Grid>
</mah:MetroWindow>
using CefSharp.DevTools.WebAudio;
using Google.Apis.Services;
using Google.Apis.YouTube.v3;
using Google.Apis.YouTube.v3.Data;
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 wp11_MovieFinder.Models;
namespace wp11_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} 예고편";
}
// 부모에서 객체를 통채로 가져오기 가능
public TrailerWindow(MovieItem movie) : this()
{
LblMovieName.Content = $"{movie.Title} 예고편";
}
//화면 로드 완료후에 YouTubeAPI 실행
private void MetroWindow_Loaded(object sender, RoutedEventArgs e)
{
youtubeItems = new List<YoutubeItem>(); //초기화
SearchYoutubeApi();
}
private async void SearchYoutubeApi()
{
await LoadDataCollection();
LsvResult.ItemsSource = youtubeItems;
}
private async Task LoadDataCollection()
{
var youtubeService = new YouTubeService(
new BaseClientService.Initializer()
{
ApiKey = "AIzaSyBFgCk2MCu91cEjgZJdu8eqQjNYjJKCx8c",
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"))
{
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(); // 리소스 해제(!)
}
}
}