Skip to content

Commit 152bfd6

Browse files
authored
Merge pull request #105 from david-risney/refactor-mainwindow
Refactor MainWindow
2 parents 8ad18f6 + 40abed2 commit 152bfd6

16 files changed

+1196
-771
lines changed

wv2util/MainWindow.xaml

+35-378
Large diffs are not rendered by default.

wv2util/MainWindow.xaml.cs

+10-393
Large diffs are not rendered by default.

wv2util/Pages/AboutPage.xaml

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<Page x:Class="wv2util.AboutPage"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:local="clr-namespace:wv2util"
7+
mc:Ignorable="d"
8+
d:DesignHeight="450" d:DesignWidth="800"
9+
Title="AboutPage">
10+
<Page.Resources>
11+
<Style x:Key="heading" TargetType="Label">
12+
<Setter Property="FontSize" Value="24" />
13+
</Style>
14+
15+
<Style x:Key="subHeading" TargetType="Label">
16+
<Setter Property="FontSize" Value="16" />
17+
</Style>
18+
</Page.Resources>
19+
<TextBlock HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="20" >
20+
<Image Source="../logo.ico" Height="128" Width="128" Margin="0,0,20,0"/>
21+
<TextBlock>
22+
<Label Style="{StaticResource heading}" Content="WebView2Utilities" Margin="0,0,0,0" HorizontalAlignment="Left"/>
23+
<LineBreak/>
24+
<TextBlock FontWeight="Bold" x:Name="VersionInfo">vN.N.N.N</TextBlock>
25+
<LineBreak/>
26+
<TextBlock>This is WebView2Utilities. It helps with developing and debugging Microsoft Edge WebView2 usage.</TextBlock>
27+
<LineBreak/>
28+
<Hyperlink NavigateUri="https://github.com/david-risney/WebView2Utilities" RequestNavigate="Hyperlink_RequestNavigate">
29+
WebView2 Tools GitHub
30+
</Hyperlink>
31+
<LineBreak/>
32+
<Hyperlink NavigateUri="https://docs.microsoft.com/en-us/microsoft-edge/webview2/" RequestNavigate="Hyperlink_RequestNavigate">
33+
WebView2 Documentation
34+
</Hyperlink>
35+
<LineBreak/>
36+
<LineBreak/>
37+
</TextBlock>
38+
<LineBreak/>
39+
<TextBlock FontSize="16" Margin="0,10,0,10">Latest WebView2 News</TextBlock>
40+
<LineBreak/>
41+
<InlineUIContainer>
42+
<StackPanel Margin="10,0,0,0" x:Name="NewsPanel" />
43+
</InlineUIContainer>
44+
<LineBreak/>
45+
<Hyperlink NavigateUri="https://github.com/MicrosoftEdge/WebView2Announcements/issues" RequestNavigate="Hyperlink_RequestNavigate">
46+
More news ...
47+
</Hyperlink>
48+
</TextBlock>
49+
</Page>

wv2util/Pages/AboutPage.xaml.cs

+145
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
using Markdig.Wpf;
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Diagnostics;
5+
using System.Linq;
6+
using System.Net.Http;
7+
using System.Text;
8+
using System.Text.Json;
9+
using System.Threading.Tasks;
10+
using System.Windows;
11+
using System.Windows.Controls;
12+
using System.Windows.Data;
13+
using System.Windows.Documents;
14+
using System.Windows.Input;
15+
using System.Windows.Media;
16+
using System.Windows.Media.Imaging;
17+
using System.Windows.Navigation;
18+
using System.Windows.Shapes;
19+
20+
namespace wv2util
21+
{
22+
/// <summary>
23+
/// Interaction logic for AboutPage.xaml
24+
/// </summary>
25+
public partial class AboutPage : Page
26+
{
27+
public AboutPage()
28+
{
29+
InitializeComponent();
30+
VersionInfo.Text = "v" + VersionUtil.GetWebView2UtilitiesVersion();
31+
GenerateNewsBlocksAsync();
32+
}
33+
34+
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
35+
{
36+
if (e.Uri.IsFile)
37+
{
38+
ProcessUtil.OpenExplorerToFile(e.Uri.LocalPath);
39+
}
40+
else
41+
{
42+
Process.Start(new ProcessStartInfo(e.Uri.AbsoluteUri));
43+
}
44+
e.Handled = true;
45+
}
46+
47+
private void Hyperlink_ExecutedRouted(object sender, ExecutedRoutedEventArgs e)
48+
{
49+
try
50+
{
51+
Process.Start(e.Parameter.ToString());
52+
}
53+
catch (Exception ex)
54+
{
55+
Console.WriteLine($"Error: {ex.Message}");
56+
}
57+
}
58+
59+
private static string s_newsLink = "https://api.github.com/repos/MicrosoftEdge/WebView2Announcements/issues";
60+
private async Task<string> GetNewsDataAsync()
61+
{
62+
var client = new HttpClient();
63+
client.DefaultRequestHeaders.Accept.Clear();
64+
client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/vnd.github.v3+json"));
65+
client.DefaultRequestHeaders.Add("User-Agent", ".NET Foundation Repository Reporter");
66+
67+
var response = await client.GetAsync(s_newsLink);
68+
if (response.IsSuccessStatusCode)
69+
return await response.Content.ReadAsStringAsync();
70+
else
71+
return await Task.FromResult($"{{ \"error\": \"{response.StatusCode}\" }}");
72+
}
73+
74+
private Dictionary<TextBlock, UIElement> m_newsBodyCollapsedControllerMap = new Dictionary<TextBlock, UIElement>();
75+
private async void GenerateNewsBlocksAsync()
76+
{
77+
string newsData = await GetNewsDataAsync();
78+
var newsJson = JsonSerializer.Deserialize<JsonElement>(newsData);
79+
int newsDisplayed = 3;
80+
int bodyFontSize = 12;
81+
82+
if (newsJson.ValueKind != JsonValueKind.Null &&
83+
newsJson.ValueKind == JsonValueKind.Array &&
84+
newsJson.EnumerateArray().Any())
85+
{
86+
for (int i = 0; i < newsDisplayed && i < newsJson.GetArrayLength(); i++)
87+
{
88+
// Skip a newsBlock when the data is invalid.
89+
if (newsJson[i].ValueKind != JsonValueKind.Object ||
90+
!newsJson[i].TryGetProperty("title", out var title) ||
91+
!newsJson[i].TryGetProperty("body", out var body))
92+
{
93+
continue;
94+
}
95+
96+
// Add the title to the block.
97+
TextBlock newsBlock = new TextBlock
98+
{
99+
Text = title.GetString(),
100+
FontSize = bodyFontSize + 2,
101+
Margin = new Thickness(10, 10, 0, 0),
102+
Cursor = Cursors.Hand
103+
};
104+
105+
// Add body content to the block.
106+
MarkdownViewer bodyBlock = new MarkdownViewer
107+
{
108+
Markdown = body.GetString(),
109+
FontSize = bodyFontSize,
110+
};
111+
foreach (Block block in bodyBlock.Document.Blocks)
112+
if (block.FontSize > bodyFontSize)
113+
block.FontSize = bodyFontSize;
114+
bodyBlock.CommandBindings.Add(new CommandBinding(Commands.Hyperlink, Hyperlink_ExecutedRouted));
115+
Grid bodyGrid = new Grid
116+
{
117+
Children = { bodyBlock },
118+
Width = 500,
119+
};
120+
121+
// Enable click to collapse function.
122+
newsBlock.MouseDown += NewsBlock_Click;
123+
m_newsBodyCollapsedControllerMap[newsBlock] = bodyGrid;
124+
bodyGrid.Visibility = Visibility.Collapsed;
125+
126+
newsBlock.Inlines.Add(new LineBreak());
127+
newsBlock.Inlines.Add(bodyGrid);
128+
NewsPanel.Children.Add(newsBlock);
129+
}
130+
}
131+
}
132+
133+
private void NewsBlock_Click(object sender, MouseButtonEventArgs e)
134+
{
135+
if (sender is TextBlock clickedTextBlock && m_newsBodyCollapsedControllerMap.ContainsKey(clickedTextBlock))
136+
{
137+
UIElement targetContainer = m_newsBodyCollapsedControllerMap[clickedTextBlock];
138+
targetContainer.Visibility = targetContainer.Visibility == Visibility.Visible
139+
? Visibility.Collapsed
140+
: Visibility.Visible;
141+
}
142+
}
143+
144+
}
145+
}

wv2util/Pages/AppOverridesPage.xaml

+83
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<Page x:Class="wv2util.AppOverridesPage"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
5+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
6+
xmlns:local="clr-namespace:wv2util"
7+
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
8+
mc:Ignorable="d"
9+
d:DesignHeight="450" d:DesignWidth="800"
10+
Title="AppOverridesPage">
11+
<Page.Resources>
12+
<ObjectDataProvider x:Key="AppOverrideList" ObjectType="{x:Type local:AppState}" MethodName="GetAppOverrideList"/>
13+
<ObjectDataProvider x:Key="HostAppList" ObjectType="{x:Type local:AppState}" MethodName="GetHostAppList"/>
14+
<ObjectDataProvider x:Key="RuntimeList" ObjectType="{x:Type local:AppState}" MethodName="GetRuntimeList"/>
15+
16+
<CollectionViewSource Source="{StaticResource AppOverrideList}" x:Key="AppOverrideSortedList">
17+
<CollectionViewSource.SortDescriptions>
18+
<scm:SortDescription PropertyName="PrecedenceCategory" Direction="Ascending"/>
19+
</CollectionViewSource.SortDescriptions>
20+
</CollectionViewSource>
21+
22+
<local:NullToBooleanConverter x:Key="NullToBooleanConverter"/>
23+
24+
<DataTemplate x:Key="AppOverrideListTemplate">
25+
<TextBlock Text="{Binding Path=DisplayLabel}" />
26+
</DataTemplate>
27+
</Page.Resources>
28+
29+
<Grid DataContext="{Binding Source={StaticResource AppOverrideSortedList}}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
30+
<ListBox
31+
x:Name="AppOverrideListBox"
32+
ItemsSource="{Binding}"
33+
ItemTemplate="{StaticResource AppOverrideListTemplate}"
34+
IsSynchronizedWithCurrentItem="True"
35+
SelectedIndex="0"
36+
HorizontalAlignment="Left" Width="322" Margin="10,10,0,30">
37+
</ListBox>
38+
<Button x:Name="AddNew" Content="Add New" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="75" Margin="10,0,0,5" Click="AddNewButton_Click"/>
39+
<Button x:Name="RemoveButton" IsEnabled="{Binding Path=/CanRemove}" Content="Remove" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="75" Margin="257,0,0,5" RenderTransformOrigin="0.597,-3.701" Click="RemoveButton_Click"/>
40+
41+
<Label Content="Host app exe" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="337,17,0,0" Width="126" />
42+
<local:TextComboBox x:Name="AppOverrideHostAppComboBox" IsEditable="true" ItemsSource="{Binding Source={StaticResource HostAppList}}" DisplayMemberPath="ExecutableName" TextSearch.TextPath="ExecutableName" ToolTip="E.g. 'example.exe'\nThe filename (not full path) of the executable of the desired host application." Text="{Binding Path=/HostApp, UpdateSourceTrigger=PropertyChanged}" IsEnabled="{Binding Path=/CanChangeHostApp,UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Top" Margin="468,17,68,0" ScrollViewer.CanContentScroll="True" VerticalContentAlignment="Center" Height="26"/>
43+
44+
<GroupBox Height="180" VerticalAlignment="Top" Margin="339,48,10,0">
45+
<GroupBox.Header>
46+
<Label>Runtime</Label>
47+
</GroupBox.Header>
48+
<Grid>
49+
<RadioButton Name="RuntimeScenarioEvergreen" IsChecked="{Binding Path=/IsRuntimeEvergreen, UpdateSourceTrigger=PropertyChanged}" Content="Evergreen (Stable)" ToolTip="Use the installed WebView2 Runtime or if not available the first of Beta, Dev, or Canary Edge browser install." GroupName="RuntimeScenario" Margin="10,0" VerticalAlignment="Top" Height="26" VerticalContentAlignment="Center"/>
50+
<RadioButton Name="RuntimeScenarioEvergreenPreview" IsChecked="{Binding Path=/IsRuntimeEvergreenPreview, UpdateSourceTrigger=PropertyChanged}" Content="Evergreen with preview build" ToolTip="Use the first of Canary, Dev, or Beta Edge browser install or if none of those then the WebView2 Runtime." GroupName="RuntimeScenario" Margin="10,26,-10,0" VerticalAlignment="Top" Height="26" VerticalContentAlignment="Center"/>
51+
<CheckBox IsEnabled="{Binding Path=/IsRuntimeEvergreenPreview}" Name="RuntimeScenarioReverseSearchOrder" IsChecked="{Binding Path=/ReverseSearchOrder, UpdateSourceTrigger=PropertyChanged}" Content="Reverse search order" ToolTip="Reverse the channels search order to prefer least stable build." Margin="55,52,-10,0" VerticalAlignment="Top" Height="26" VerticalContentAlignment="Center"/>
52+
<CheckBox IsEnabled="{Binding Path=/IsRuntimeEvergreenPreview}" Name="RuntimeScenarioEvergreenPreviewCanary" IsChecked="{Binding Path=/IsRuntimeCanary, UpdateSourceTrigger=PropertyChanged}" Content="Canary" ToolTip="Use Canary Edge browser install or the WebView2 Runtime if Dev is not available." Margin="55,78,-10,0" VerticalAlignment="Top" Height="26" VerticalContentAlignment="Center"/>
53+
<CheckBox IsEnabled="{Binding Path=/IsRuntimeEvergreenPreview}" Name="RuntimeScenarioEvergreenPreviewDev" IsChecked="{Binding Path=/IsRuntimeDev, UpdateSourceTrigger=PropertyChanged}" Content="Dev" ToolTip="Use Dev Edge browser install or the WebView2 Runtime if Dev is not available." Margin="140,78,-10,0" VerticalAlignment="Top" Height="26" VerticalContentAlignment="Center"/>
54+
<CheckBox IsEnabled="{Binding Path=/IsRuntimeEvergreenPreview}" Name="RuntimeScenarioEvergreenPreviewBeta" IsChecked="{Binding Path=/IsRuntimeBeta, UpdateSourceTrigger=PropertyChanged}" Content="Beta" ToolTip="Use Beta Edge browser install or the WebView2 Runtime if Dev is not available." Margin="210,78,-10,0" VerticalAlignment="Top" Height="26" VerticalContentAlignment="Center"/>
55+
<CheckBox IsEnabled="{Binding Path=/IsRuntimeEvergreenPreview}" Name="RuntimeScenarioEvergreenPreviewStable" IsChecked="{Binding Path=/IsRuntimeStable, UpdateSourceTrigger=PropertyChanged}" Content="Stable" ToolTip="Use the stable WebView2 Runtime." Margin="280,78,-10,0" VerticalAlignment="Top" Height="26" VerticalContentAlignment="Center"/>
56+
<RadioButton Name="RuntimeScenarioFixedVersion" IsChecked="{Binding Path=/IsRuntimeFixedVersion, UpdateSourceTrigger=PropertyChanged}" Content="Fixed Version" ToolTip="Use the WebView2 Runtime at the specified path" GroupName="RuntimeScenario" Margin="10,106,-10,0" VerticalAlignment="Top" Height="26" VerticalContentAlignment="Center"/>
57+
</Grid>
58+
</GroupBox>
59+
<local:TextComboBox x:Name="AppOverrideRuntimePathComboBox" IsEditable="true" ItemsSource="{Binding Source={StaticResource RuntimeList}}" DisplayMemberPath="RuntimeLocation" TextSearch.TextPath="RuntimeLocation" ToolTip="The full path of the WebView2 Runtime or non-stable browser. The path should contain msedgewebview2.exe." IsEnabled="{Binding Path=/IsRuntimeFixedVersion, UpdateSourceTrigger=PropertyChanged}" Text="{Binding Path=/RuntimePath, UpdateSourceTrigger=PropertyChanged}" Height="26" VerticalAlignment="Top" Margin="468,185,68,0" VerticalContentAlignment="Center"/>
60+
<Button IsEnabled="{Binding Path=/IsRuntimeFixedVersion}" x:Name="AppOverrideRuntimePathButton" Content="..." HorizontalAlignment="Right" VerticalAlignment="Top" Width="37" Margin="0,188,21,0" Click="AppOverrideRuntimePathButton_Click"/>
61+
62+
<GroupBox Height="120" VerticalAlignment="Top" Margin="339,227,10,0">
63+
<GroupBox.Header>
64+
<Label Content="Browser arguments"/>
65+
</GroupBox.Header>
66+
</GroupBox>
67+
<Label Content="Arguments" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="354,251,0,0" Width="109" />
68+
<TextBox ToolTip="Additional arguments to include on the command line for msedgewebview2.exe." x:Name="AppOverrideBrowserArgumentsTextBox" Text="{Binding Path=/BrowserArguments, UpdateSourceTrigger=PropertyChanged}" Height="26" TextWrapping="Wrap" VerticalAlignment="Top" Margin="468,251,68,0" ScrollViewer.CanContentScroll="True" MaxLines="1" VerticalContentAlignment="Center"/>
69+
<Button x:Name="AppOverrideBrowserArgumentsButton" Content="?" HorizontalAlignment="Right" VerticalAlignment="Top" Width="36" Margin="0,254,21,0" Click="AppOverrideBrowserArgumentsButton_Click"/>
70+
<CheckBox x:Name="AppOverrideArgumentsAutoOpenDevTools" Content="Auto open DevTools" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="354,293,0,0" IsChecked="{Binding /IsCommonBrowserArgumentEnabledAutoOpenDevTools}"/>
71+
<CheckBox x:Name="AppOverrideArgumentsLogging" Content="Logging" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="354,320,0,0" IsChecked="{Binding /IsCommonBrowserArgumentEnabledLogging}"/>
72+
73+
<Label Content="User data path" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="337,358,0,0" Width="126"/>
74+
<TextBox ToolTip="The full path of the user data folder. The selected folder should contain an EBWebView subfolder." x:Name="AppOverrideUserDataPathTextBox" Text="{Binding Path=/UserDataPath, UpdateSourceTrigger=PropertyChanged}" Height="26" TextWrapping="Wrap" VerticalAlignment="Top" Margin="468,358,68,0" ScrollViewer.CanContentScroll="True" MaxLines="1" VerticalContentAlignment="Center"/>
75+
<Button x:Name="AppOverrideUserDataPathButton" Content="..." HorizontalAlignment="Right" VerticalAlignment="Top" Width="36" Margin="0,361,21,0" Click="AppOverrideUserDataPathButton_Click"/>
76+
77+
<Label Content="{Binding Path=/StorageKindDescription,UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="337,389,0,0" Width="747"/>
78+
79+
<Button x:Name="EnvVarButton" Content="Edit Env Var" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="100" Margin="0,0,120,5" Click="EnvVarButton_Click"/>
80+
<Button x:Name="RegEditButton" Content="Launch RegEdit" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="100" Margin="0,0,10,5" Click="RegEditButton_Click"/>
81+
82+
</Grid>
83+
</Page>

0 commit comments

Comments
 (0)