■ Dispatcher 클래스의 Run 정적 메소드를 사용해 다중 윈도우 다중 스레드를 사용하는 방법을 보여준다. 이 메소드는 새 스레드의 시작점이다. 이 스레드의 제어하에 새 창을 만든다. WPF는 새 스레드를 관리하기 위해 새 Dispatcher를 자동으로 만든다. 창을 기능적으로 만들기 위해 해야 할 일은 Dispatcher를 시작하는 것뿐이다.
▶ MainWindow.xaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<Window x:Class="TestProject.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="800" Height="600" Title="TestProject" FontFamily="나눔고딕코딩" FontSize="16"> <Grid Margin="10"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Orientation="Horizontal"> <Button Name="newWindowButton" Width="100" Height="30" Content="New Window" /> <TextBox Name="newLocationTextBox" Margin="10 0 0 0" Width="500" BorderThickness="1" BorderBrush="Black" VerticalContentAlignment="Center" /> <Button Name="browseButton" Margin="10 0 0 0" Width="100" Height="30" Content="Browse" /> </StackPanel> <Frame Name="frame" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="0 10 0 0" BorderThickness="1" BorderBrush="Black" NavigationUIVisibility="Hidden" Source="https://www.daum.net" /> </Grid> </Window> |
▶ MainWindow.xaml.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
using System; using System.Net; using System.Reflection; using System.Threading; using System.Windows; using System.Windows.Navigation; using System.Windows.Threading; namespace TestProject { /// <summary> /// 메인 윈도우 /// </summary> public partial class MainWindow : Window { //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////////////////////////////////////////////// Public #region 생성자 - MainWindow() /// <summary> /// 생성자 /// </summary> public MainWindow() { InitializeComponent(); ServicePointManager.Expect100Continue = true; ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 | SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12; ServicePointManager.ServerCertificateValidationCallback = delegate { return true; }; Loaded += Window_Loaded; this.newWindowButton.Click += newWindowButton_Click; this.browseButton.Click += browseButton_Click; this.frame.Navigated += frame_Navigated; } #endregion //////////////////////////////////////////////////////////////////////////////////////////////////// Method ////////////////////////////////////////////////////////////////////////////////////////// Private //////////////////////////////////////////////////////////////////////////////// Event #region 윈도우 로드시 처리하기 - Window_Loaded(sender, e) /// <summary> /// 윈도우 로드시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void Window_Loaded(object sender, RoutedEventArgs e) { this.frame.Source = new Uri("https://www.daum.net"); } #endregion #region New Window 버튼 클릭시 처리하기 - newWindowButton_Click(sender, e) /// <summary> /// New Window 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void newWindowButton_Click(object sender, RoutedEventArgs e) { Thread thread = new Thread(ProcessNewWindow); thread.IsBackground = true; thread.SetApartmentState(ApartmentState.STA); thread.Start(); } #endregion #region Browse 버튼 클릭시 처리하기 - browseButton_Click(sender, e) /// <summary> /// Browse 버튼 클릭시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void browseButton_Click(object sender, RoutedEventArgs e) { this.frame.Source = new Uri(this.newLocationTextBox.Text); } #endregion #region 프레임 이동 완료시 처리하기 - frame_Navigated(sender, e) /// <summary> /// 프레임 이동 완료시 처리하기 /// </summary> /// <param name="sender">이벤트 발생자</param> /// <param name="e">이벤트 인자</param> private void frame_Navigated(object sender, NavigationEventArgs e) { NavigationService navigationService = this.frame.NavigationService; dynamic browser = navigationService.GetType().GetField("_webBrowser", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(navigationService); dynamic iWebBrowser2 = browser.GetType().GetField("_axIWebBrowser2", BindingFlags.NonPublic | BindingFlags.Instance).GetValue(browser); iWebBrowser2.Silent = true; } #endregion //////////////////////////////////////////////////////////////////////////////// Function #region 새 윈도우 처리하기 - ProcessNewWindow() /// <summary> /// 새 윈도우 처리하기 /// </summary> private void ProcessNewWindow() { MainWindow mainWindow = new MainWindow(); mainWindow.Show(); Dispatcher.Run(); } #endregion } } |