Create main window viewmodel.

This commit is contained in:
Jared Goodwin 2020-02-18 21:48:50 -08:00
parent 57510efa10
commit c6b19120d9
13 changed files with 352 additions and 9 deletions

View File

@ -38,7 +38,7 @@
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon>
<ApplicationIcon>Assets\favicon.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
@ -76,6 +76,7 @@
<Compile Include="Services\InstallerService.cs" />
<Compile Include="Services\Logger.cs" />
<Compile Include="ViewModels\MainWindowViewModel.cs" />
<Compile Include="ViewModels\ViewModelBase.cs" />
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@ -118,9 +119,11 @@
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Resource Include="favicon.ico" />
<Resource Include="Assets\favicon.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Assets\Remotely_Icon.png" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Fody.6.1.0\build\Fody.targets" Condition="Exists('..\packages\Fody.6.1.0\build\Fody.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">

View File

@ -4,6 +4,27 @@
xmlns:local="clr-namespace:Remotely.Agent.Installer.Win"
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="TitlebarButton" TargetType="Button">
<Setter Property="Background" Value="#FF464646"></Setter>
<Setter Property="DockPanel.Dock" Value="Right"></Setter>
<Setter Property="HorizontalAlignment" Value="Right"></Setter>
<Setter Property="BorderBrush" Value="{x:Null}"></Setter>
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="FontWeight" Value="Bold"></Setter>
<Setter Property="Height" Value="30"></Setter>
<Setter Property="Width" Value="30"></Setter>
<Setter Property="Cursor" Value="Hand"></Setter>
<Setter Property="Margin" Value="5,0,5,0"></Setter>
</Style>
<Style x:Key="SectionHeader" TargetType="TextBlock">
<Setter Property="FontWeight" Value="Bold"></Setter>
<Setter Property="FontSize" Value="18"></Setter>
</Style>
<Style x:Key="NormalButton" TargetType="Button">
<Setter Property="Background" Value="White"></Setter>
<Setter Property="BorderThickness" Value="1"></Setter>
<Setter Property="BorderBrush" Value="Black"></Setter>
<Setter Property="Padding" Value="6,4"></Setter>
</Style>
</Application.Resources>
</Application>

View File

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

View File

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<Costura />
</Weavers>

View File

@ -0,0 +1,111 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="Costura" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
</xs:annotation>
</xs:element>
</xs:all>
<xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
<xs:annotation>
<xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCompression" type="xs:boolean">
<xs:annotation>
<xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="DisableCleanup" type="xs:boolean">
<xs:annotation>
<xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="LoadAtModuleInit" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
<xs:annotation>
<xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="ExcludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="IncludeAssemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged32Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="Unmanaged64Assemblies" type="xs:string">
<xs:annotation>
<xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="PreloadOrder" type="xs:string">
<xs:annotation>
<xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@ -3,10 +3,88 @@
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:ViewModels="clr-namespace:Remotely.Agent.Installer.Win.ViewModels"
xmlns:local="clr-namespace:Remotely.Agent.Installer.Win"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" Icon="favicon.ico">
WindowStyle="None"
ResizeMode="NoResize"
MouseLeftButtonDown="Window_MouseLeftButtonDown"
Loaded="Window_Loaded"
Title="Remotely Installer" Height="350" Width="500" Icon="Assets/favicon.ico">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
<Window.DataContext>
<ViewModels:MainWindowViewModel/>
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Row="0" Height="50" Background="#FF464646" VerticalAlignment="Top">
<DockPanel Margin="10,0,0,0">
<Image Height="50" Width="50" Source="Assets/Remotely_Icon.png" Margin="0,0,10,0"></Image>
<TextBlock Foreground="DeepSkyBlue" FontWeight="Bold" FontSize="20" VerticalAlignment="Center">Remotely Installer</TextBlock>
<Button Style="{StaticResource TitlebarButton}" Click="CloseButton_Click" Content="X" />
<Button Style="{StaticResource TitlebarButton}" Click="MinimizeButton_Click" Content="_"/>
</DockPanel>
</Border>
<Grid Grid.Row="1" Margin="10,15,10,0">
<StackPanel Visibility="{Binding IsServiceMissing, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock Style="{StaticResource SectionHeader}" Text="{Binding HeaderMessage}"></TextBlock>
<TextBlock TextWrapping="Wrap" Margin="25,5,0,0">
<Run>Organization: </Run>
<Run Text="{Binding OrganizationName}"></Run>
</TextBlock>
<TextBlock TextWrapping="Wrap" Margin="25,5,0,0">
<Run>Server URL: </Run>
<Run Text="{Binding ServerUrl}"></Run>
</TextBlock>
<TextBlock TextWrapping="Wrap" Margin="0,15,0,0" Text="{Binding SubMessage}"></TextBlock>
<ProgressBar Height="25" Margin="0,25,0,0" Value="{Binding Progress}"></ProgressBar>
<TextBlock TextWrapping="Wrap" Margin="0,15,0,0" Text="{Binding StatusMessage}"></TextBlock>
</StackPanel>
<StackPanel Visibility="{Binding IsServiceInstalled, Converter={StaticResource BooleanToVisibilityConverter}}">
<TextBlock Style="{StaticResource SectionHeader}" Text="{Binding HeaderMessage}"></TextBlock>
<TextBlock TextWrapping="Wrap" Margin="25,5,0,0" Visibility="{Binding IsServiceMissing, Converter={StaticResource BooleanToVisibilityConverter}}">
<Run>Organization: </Run>
<Run Text="{Binding OrganizationName}"></Run>
</TextBlock>
<TextBlock TextWrapping="Wrap" Margin="25,5,0,0" Visibility="{Binding IsServiceMissing, Converter={StaticResource BooleanToVisibilityConverter}}">
<Run>Server URL: </Run>
<Run Text="{Binding ServerUrl}"></Run>
</TextBlock>
<TextBlock TextWrapping="Wrap" Margin="0,15,0,0" Text="{Binding SubMessage}"></TextBlock>
</StackPanel>
</Grid>
<DockPanel Margin="10" Grid.Row="2">
<Button DockPanel.Dock="Right"
HorizontalAlignment="Right"
Style="{StaticResource NormalButton}"
Margin="5,0,0,0">
Close
</Button>
<Button DockPanel.Dock="Right"
HorizontalAlignment="Right"
Style="{StaticResource NormalButton}"
Margin="5,0,0,0"
Visibility="{Binding IsServiceMissing, Converter={StaticResource BooleanToVisibilityConverter}}">
Install
</Button>
<Button DockPanel.Dock="Right"
HorizontalAlignment="Right"
Style="{StaticResource NormalButton}"
Margin="5,0,0,0"
Visibility="{Binding IsServiceInstalled, Converter={StaticResource BooleanToVisibilityConverter}}">
Uninstall
</Button>
</DockPanel>
</Grid>
</Window>

View File

@ -1,4 +1,5 @@
using System;
using Remotely.Agent.Installer.Win.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@ -24,5 +25,25 @@ namespace Remotely.Agent.Installer.Win
{
InitializeComponent();
}
private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DragMove();
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await (DataContext as MainWindowViewModel).Init();
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
App.Current.Shutdown();
}
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
this.WindowState = WindowState.Minimized;
}
}
}

View File

@ -9,8 +9,96 @@ using System.Threading.Tasks;
namespace Remotely.Agent.Installer.Win.ViewModels
{
public class MainWindowViewModel
public class MainWindowViewModel : ViewModelBase
{
private string headerMessage = "Install the Remotely service.";
private bool isServiceInstalled;
private bool isServiceMissing = true;
private string subMessage = "Installing the Remotely service will allow remote access by the above service provider.";
private string statusMessage;
private int progress = 50;
public string HeaderMessage
{
get
{
return headerMessage;
}
set
{
headerMessage = value;
FirePropertyChanged(nameof(HeaderMessage));
}
}
public int Progress
{
get
{
return progress;
}
set
{
progress = value;
FirePropertyChanged(nameof(Progress));
}
}
public bool IsServiceInstalled
{
get
{
return isServiceInstalled;
}
set
{
isServiceInstalled = value;
FirePropertyChanged(nameof(IsServiceInstalled));
}
}
public bool IsServiceMissing
{
get
{
return isServiceMissing;
}
set
{
isServiceMissing = value;
FirePropertyChanged(nameof(IsServiceMissing));
}
}
public string SubMessage
{
get
{
return subMessage;
}
set
{
subMessage = value;
FirePropertyChanged(nameof(SubMessage));
}
}
public string StatusMessage
{
get
{
return statusMessage;
}
set
{
statusMessage = value;
FirePropertyChanged(nameof(StatusMessage));
}
}
public async Task Init()
{
}
public InstallerSettings ReadInstallerSettings()
{
try

View File

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Remotely.Agent.Installer.Win.ViewModels
{
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void FirePropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View File

Before

Width:  |  Height:  |  Size: 103 KiB

After

Width:  |  Height:  |  Size: 103 KiB

BIN
Assets/Remotely_Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@ -19,10 +19,9 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Utilities", "Utilities", "{
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Assets", "Assets", "{D96B47F6-EF3E-4AF6-A1BE-006D531DDBA4}"
ProjectSection(SolutionItems) = preProject
Assets\Remotely_Icon.ico = Assets\Remotely_Icon.ico
Assets\Remotely_Icon.pdn = Assets\Remotely_Icon.pdn
Assets\Remotely_Icon.png = Assets\Remotely_Icon.png
Assets\Remotely_Icon_Transparent.ico = Assets\Remotely_Icon_Transparent.ico
Assets\Remotely_Icon_Transparent.png = Assets\Remotely_Icon_Transparent.png
Assets\Remotely_Logo.png = Assets\Remotely_Logo.png
EndProjectSection
EndProject