@ -0,0 +1,51 @@ |
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00 |
||||||
|
# Visual Studio Version 16 |
||||||
|
VisualStudioVersion = 16.0.29709.97 |
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1 |
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EyesAndEars.UWP", "EyesAndEars.UWP\EyesAndEars.UWP.csproj", "{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}" |
||||||
|
EndProject |
||||||
|
Global |
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution |
||||||
|
Debug|ARM = Debug|ARM |
||||||
|
Debug|ARM64 = Debug|ARM64 |
||||||
|
Debug|x64 = Debug|x64 |
||||||
|
Debug|x86 = Debug|x86 |
||||||
|
Release|ARM = Release|ARM |
||||||
|
Release|ARM64 = Release|ARM64 |
||||||
|
Release|x64 = Release|x64 |
||||||
|
Release|x86 = Release|x86 |
||||||
|
EndGlobalSection |
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|ARM.ActiveCfg = Debug|ARM |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|ARM.Build.0 = Debug|ARM |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|ARM.Deploy.0 = Debug|ARM |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|ARM64.ActiveCfg = Debug|ARM64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|ARM64.Build.0 = Debug|ARM64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|ARM64.Deploy.0 = Debug|ARM64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|x64.ActiveCfg = Debug|x64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|x64.Build.0 = Debug|x64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|x64.Deploy.0 = Debug|x64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|x86.ActiveCfg = Debug|x86 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|x86.Build.0 = Debug|x86 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Debug|x86.Deploy.0 = Debug|x86 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|ARM.ActiveCfg = Release|ARM |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|ARM.Build.0 = Release|ARM |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|ARM.Deploy.0 = Release|ARM |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|ARM64.ActiveCfg = Release|ARM64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|ARM64.Build.0 = Release|ARM64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|ARM64.Deploy.0 = Release|ARM64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|x64.ActiveCfg = Release|x64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|x64.Build.0 = Release|x64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|x64.Deploy.0 = Release|x64 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|x86.ActiveCfg = Release|x86 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|x86.Build.0 = Release|x86 |
||||||
|
{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}.Release|x86.Deploy.0 = Release|x86 |
||||||
|
EndGlobalSection |
||||||
|
GlobalSection(SolutionProperties) = preSolution |
||||||
|
HideSolutionNode = FALSE |
||||||
|
EndGlobalSection |
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution |
||||||
|
SolutionGuid = {F3E6EBEC-0578-466F-9C2A-A9475D9811A7} |
||||||
|
EndGlobalSection |
||||||
|
EndGlobal |
@ -0,0 +1,7 @@ |
|||||||
|
<Application |
||||||
|
x:Class="EyesAndEars.UWP.App" |
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||||
|
xmlns:local="using:EyesAndEars.UWP"> |
||||||
|
|
||||||
|
</Application> |
@ -0,0 +1,80 @@ |
|||||||
|
using System; |
||||||
|
using Windows.ApplicationModel; |
||||||
|
using Windows.ApplicationModel.Activation; |
||||||
|
using Windows.UI.Xaml; |
||||||
|
using Windows.UI.Xaml.Controls; |
||||||
|
using Windows.UI.Xaml.Navigation; |
||||||
|
|
||||||
|
namespace EyesAndEars.UWP { |
||||||
|
/// <summary> |
||||||
|
/// Provides application-specific behavior to supplement the default Application class. |
||||||
|
/// </summary> |
||||||
|
sealed partial class App : Application { |
||||||
|
/// <summary> |
||||||
|
/// Initializes the singleton application object. This is the first line of authored code |
||||||
|
/// executed, and as such is the logical equivalent of main() or WinMain(). |
||||||
|
/// </summary> |
||||||
|
public App() { |
||||||
|
this.InitializeComponent(); |
||||||
|
this.Suspending += OnSuspending; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Invoked when the application is launched normally by the end user. Other entry points |
||||||
|
/// will be used such as when the application is launched to open a specific file. |
||||||
|
/// </summary> |
||||||
|
/// <param name="e">Details about the launch request and process.</param> |
||||||
|
protected override void OnLaunched(LaunchActivatedEventArgs e) { |
||||||
|
Frame rootFrame = Window.Current.Content as Frame; |
||||||
|
|
||||||
|
// Do not repeat app initialization when the Window already has content, |
||||||
|
// just ensure that the window is active |
||||||
|
if (rootFrame == null) { |
||||||
|
// Create a Frame to act as the navigation context and navigate to the first page |
||||||
|
rootFrame = new Frame(); |
||||||
|
|
||||||
|
rootFrame.NavigationFailed += OnNavigationFailed; |
||||||
|
|
||||||
|
if (e.PreviousExecutionState == ApplicationExecutionState.Terminated) { |
||||||
|
//TODO: Load state from previously suspended application |
||||||
|
} |
||||||
|
|
||||||
|
// Place the frame in the current Window |
||||||
|
Window.Current.Content = rootFrame; |
||||||
|
} |
||||||
|
|
||||||
|
if (e.PrelaunchActivated == false) { |
||||||
|
if (rootFrame.Content == null) { |
||||||
|
// When the navigation stack isn't restored navigate to the first page, |
||||||
|
// configuring the new page by passing required information as a navigation |
||||||
|
// parameter |
||||||
|
rootFrame.Navigate(typeof(MainPage), e.Arguments); |
||||||
|
} |
||||||
|
// Ensure the current window is active |
||||||
|
Window.Current.Activate(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Invoked when Navigation to a certain page fails |
||||||
|
/// </summary> |
||||||
|
/// <param name="sender">The Frame which failed navigation</param> |
||||||
|
/// <param name="e">Details about the navigation failure</param> |
||||||
|
void OnNavigationFailed(object sender, NavigationFailedEventArgs e) { |
||||||
|
throw new Exception("Failed to load Page " + e.SourcePageType.FullName); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Invoked when application execution is being suspended. Application state is saved |
||||||
|
/// without knowing whether the application will be terminated or resumed with the contents |
||||||
|
/// of memory still intact. |
||||||
|
/// </summary> |
||||||
|
/// <param name="sender">The source of the suspend request.</param> |
||||||
|
/// <param name="e">Details about the suspend request.</param> |
||||||
|
private void OnSuspending(object sender, SuspendingEventArgs e) { |
||||||
|
var deferral = e.SuspendingOperation.GetDeferral(); |
||||||
|
//TODO: Save application state and stop any background activity |
||||||
|
deferral.Complete(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 6.4 KiB |
After Width: | Height: | Size: 7.8 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 28 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 6.1 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 33 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 523 B |
After Width: | Height: | Size: 799 B |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 516 B |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 1.0 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.4 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 422 B |
After Width: | Height: | Size: 660 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 7.6 KiB |
After Width: | Height: | Size: 838 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 3.5 KiB |
After Width: | Height: | Size: 7.5 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 5.3 KiB |
After Width: | Height: | Size: 12 KiB |
@ -0,0 +1,245 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" /> |
||||||
|
<PropertyGroup> |
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform> |
||||||
|
<ProjectGuid>{0AEFB351-EA4D-4ED1-998A-AB0B0792E06B}</ProjectGuid> |
||||||
|
<OutputType>AppContainerExe</OutputType> |
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||||
|
<RootNamespace>EyesAndEars.UWP</RootNamespace> |
||||||
|
<AssemblyName>EyesAndEars.UWP</AssemblyName> |
||||||
|
<DefaultLanguage>en-GB</DefaultLanguage> |
||||||
|
<TargetPlatformIdentifier>UAP</TargetPlatformIdentifier> |
||||||
|
<TargetPlatformVersion Condition=" '$(TargetPlatformVersion)' == '' ">10.0.18362.0</TargetPlatformVersion> |
||||||
|
<TargetPlatformMinVersion>10.0.18362.0</TargetPlatformMinVersion> |
||||||
|
<MinimumVisualStudioVersion>14</MinimumVisualStudioVersion> |
||||||
|
<FileAlignment>512</FileAlignment> |
||||||
|
<ProjectTypeGuids>{A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
||||||
|
<WindowsXamlEnableOverview>true</WindowsXamlEnableOverview> |
||||||
|
<AppxPackageSigningEnabled>True</AppxPackageSigningEnabled> |
||||||
|
<GenerateAppInstallerFile>False</GenerateAppInstallerFile> |
||||||
|
<PackageCertificateKeyFile>EyesAndEars.UWP_TemporaryKey.pfx</PackageCertificateKeyFile> |
||||||
|
<PackageCertificateThumbprint> |
||||||
|
</PackageCertificateThumbprint> |
||||||
|
<AppxPackageSigningTimestampDigestAlgorithm>SHA256</AppxPackageSigningTimestampDigestAlgorithm> |
||||||
|
<AppxAutoIncrementPackageRevision>False</AppxAutoIncrementPackageRevision> |
||||||
|
<GenerateTestArtifacts>True</GenerateTestArtifacts> |
||||||
|
<AppxBundle>Always</AppxBundle> |
||||||
|
<AppxBundlePlatforms>x64</AppxBundlePlatforms> |
||||||
|
<HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
<OutputPath>bin\x86\Debug\</OutputPath> |
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> |
||||||
|
<NoWarn>;2008</NoWarn> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<PlatformTarget>x86</PlatformTarget> |
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<Prefer32Bit>true</Prefer32Bit> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'"> |
||||||
|
<OutputPath>bin\x86\Release\</OutputPath> |
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> |
||||||
|
<Optimize>true</Optimize> |
||||||
|
<NoWarn>;2008</NoWarn> |
||||||
|
<DebugType>pdbonly</DebugType> |
||||||
|
<PlatformTarget>x86</PlatformTarget> |
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<Prefer32Bit>true</Prefer32Bit> |
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM'"> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
<OutputPath>bin\ARM\Debug\</OutputPath> |
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> |
||||||
|
<NoWarn>;2008</NoWarn> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<PlatformTarget>ARM</PlatformTarget> |
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<Prefer32Bit>true</Prefer32Bit> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM'"> |
||||||
|
<OutputPath>bin\ARM\Release\</OutputPath> |
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> |
||||||
|
<Optimize>true</Optimize> |
||||||
|
<NoWarn>;2008</NoWarn> |
||||||
|
<DebugType>pdbonly</DebugType> |
||||||
|
<PlatformTarget>ARM</PlatformTarget> |
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<Prefer32Bit>true</Prefer32Bit> |
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|ARM64'"> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
<OutputPath>bin\ARM64\Debug\</OutputPath> |
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> |
||||||
|
<NoWarn>;2008</NoWarn> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<PlatformTarget>ARM64</PlatformTarget> |
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<Prefer32Bit>true</Prefer32Bit> |
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|ARM64'"> |
||||||
|
<OutputPath>bin\ARM64\Release\</OutputPath> |
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> |
||||||
|
<Optimize>true</Optimize> |
||||||
|
<NoWarn>;2008</NoWarn> |
||||||
|
<DebugType>pdbonly</DebugType> |
||||||
|
<PlatformTarget>ARM64</PlatformTarget> |
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<Prefer32Bit>true</Prefer32Bit> |
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x64'"> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
<OutputPath>bin\x64\Debug\</OutputPath> |
||||||
|
<DefineConstants>DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> |
||||||
|
<NoWarn>;2008</NoWarn> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<PlatformTarget>x64</PlatformTarget> |
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<Prefer32Bit>true</Prefer32Bit> |
||||||
|
<EnableGatekeeperAnalysis>true</EnableGatekeeperAnalysis> |
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'"> |
||||||
|
<OutputPath>bin\x64\Release\</OutputPath> |
||||||
|
<DefineConstants>TRACE;NETFX_CORE;WINDOWS_UWP</DefineConstants> |
||||||
|
<Optimize>true</Optimize> |
||||||
|
<NoWarn>;2008</NoWarn> |
||||||
|
<DebugType>pdbonly</DebugType> |
||||||
|
<PlatformTarget>x64</PlatformTarget> |
||||||
|
<UseVSHostingProcess>false</UseVSHostingProcess> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<Prefer32Bit>true</Prefer32Bit> |
||||||
|
<UseDotNetNativeToolchain>true</UseDotNetNativeToolchain> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup> |
||||||
|
<RestoreProjectStyle>PackageReference</RestoreProjectStyle> |
||||||
|
</PropertyGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Compile Include="App.xaml.cs"> |
||||||
|
<DependentUpon>App.xaml</DependentUpon> |
||||||
|
</Compile> |
||||||
|
<Compile Include="MainPage.xaml.cs"> |
||||||
|
<DependentUpon>MainPage.xaml</DependentUpon> |
||||||
|
</Compile> |
||||||
|
<Compile Include="Models\Device.cs" /> |
||||||
|
<Compile Include="Models\DeviceStatus.cs" /> |
||||||
|
<Compile Include="Models\LightReading.cs" /> |
||||||
|
<Compile Include="Services\DataServices.cs" /> |
||||||
|
<Compile Include="ViewModels\MainPageVM.cs" /> |
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||||
|
<Compile Include="Services\WebServices.cs" /> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<AppxManifest Include="Package.appxmanifest"> |
||||||
|
<SubType>Designer</SubType> |
||||||
|
</AppxManifest> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Content Include="Assets\LargeTile.scale-100.png" /> |
||||||
|
<Content Include="Assets\LargeTile.scale-125.png" /> |
||||||
|
<Content Include="Assets\LargeTile.scale-150.png" /> |
||||||
|
<Content Include="Assets\LargeTile.scale-200.png" /> |
||||||
|
<Content Include="Assets\LargeTile.scale-400.png" /> |
||||||
|
<Content Include="Assets\SmallTile.scale-100.png" /> |
||||||
|
<Content Include="Assets\SmallTile.scale-125.png" /> |
||||||
|
<Content Include="Assets\SmallTile.scale-150.png" /> |
||||||
|
<Content Include="Assets\SmallTile.scale-200.png" /> |
||||||
|
<Content Include="Assets\SmallTile.scale-400.png" /> |
||||||
|
<Content Include="Assets\SplashScreen.scale-100.png" /> |
||||||
|
<Content Include="Assets\SplashScreen.scale-125.png" /> |
||||||
|
<Content Include="Assets\SplashScreen.scale-150.png" /> |
||||||
|
<Content Include="Assets\SplashScreen.scale-400.png" /> |
||||||
|
<Content Include="Assets\Square150x150Logo.scale-100.png" /> |
||||||
|
<Content Include="Assets\Square150x150Logo.scale-125.png" /> |
||||||
|
<Content Include="Assets\Square150x150Logo.scale-150.png" /> |
||||||
|
<Content Include="Assets\Square150x150Logo.scale-400.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-16.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-24.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-256.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-32.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-lightunplated_targetsize-48.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-16.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-256.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-32.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.altform-unplated_targetsize-48.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.scale-100.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.scale-125.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.scale-150.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.scale-400.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-16.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-24.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-256.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-32.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-48.png" /> |
||||||
|
<Content Include="Assets\StoreLogo.scale-100.png" /> |
||||||
|
<Content Include="Assets\StoreLogo.scale-125.png" /> |
||||||
|
<Content Include="Assets\StoreLogo.scale-150.png" /> |
||||||
|
<Content Include="Assets\StoreLogo.scale-200.png" /> |
||||||
|
<Content Include="Assets\StoreLogo.scale-400.png" /> |
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-100.png" /> |
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-125.png" /> |
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-150.png" /> |
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-400.png" /> |
||||||
|
<Content Include="Images\logo.png" /> |
||||||
|
<Content Include="Properties\Default.rd.xml" /> |
||||||
|
<Content Include="Assets\LockScreenLogo.scale-200.png" /> |
||||||
|
<Content Include="Assets\SplashScreen.scale-200.png" /> |
||||||
|
<Content Include="Assets\Square150x150Logo.scale-200.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.scale-200.png" /> |
||||||
|
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" /> |
||||||
|
<Content Include="Assets\Wide310x150Logo.scale-200.png" /> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<ApplicationDefinition Include="App.xaml"> |
||||||
|
<Generator>MSBuild:Compile</Generator> |
||||||
|
<SubType>Designer</SubType> |
||||||
|
</ApplicationDefinition> |
||||||
|
<Page Include="MainPage.xaml"> |
||||||
|
<Generator>MSBuild:Compile</Generator> |
||||||
|
<SubType>Designer</SubType> |
||||||
|
</Page> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<PackageReference Include="Microsoft.NetCore.Analyzers"> |
||||||
|
<Version>2.9.8</Version> |
||||||
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> |
||||||
|
<PrivateAssets>all</PrivateAssets> |
||||||
|
</PackageReference> |
||||||
|
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform"> |
||||||
|
<Version>6.2.9</Version> |
||||||
|
</PackageReference> |
||||||
|
<PackageReference Include="System.Text.Json"> |
||||||
|
<Version>4.7.0</Version> |
||||||
|
</PackageReference> |
||||||
|
<PackageReference Include="System.Threading.Timer"> |
||||||
|
<Version>4.3.0</Version> |
||||||
|
</PackageReference> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<None Include="EyesAndEars.UWP_TemporaryKey.pfx" /> |
||||||
|
</ItemGroup> |
||||||
|
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' "> |
||||||
|
<VisualStudioVersion>14.0</VisualStudioVersion> |
||||||
|
</PropertyGroup> |
||||||
|
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsXaml\v$(VisualStudioVersion)\Microsoft.Windows.UI.Xaml.CSharp.targets" /> |
||||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
||||||
|
Other similar extension points exist, see Microsoft.Common.targets. |
||||||
|
<Target Name="BeforeBuild"> |
||||||
|
</Target> |
||||||
|
<Target Name="AfterBuild"> |
||||||
|
</Target> |
||||||
|
--> |
||||||
|
</Project> |
@ -0,0 +1,241 @@ |
|||||||
|
<Page |
||||||
|
x:Class="EyesAndEars.UWP.MainPage" |
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||||
|
xmlns:local="using:EyesAndEars.UWP" |
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" |
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" |
||||||
|
mc:Ignorable="d" |
||||||
|
Background="{ThemeResource SystemControlAcrylicWindowBrush}"> |
||||||
|
|
||||||
|
<Grid Margin="12"> |
||||||
|
|
||||||
|
<Grid.RowDefinitions> |
||||||
|
<RowDefinition Height="96"/> |
||||||
|
<RowDefinition Height="*"/> |
||||||
|
<RowDefinition Height="Auto"/> |
||||||
|
</Grid.RowDefinitions> |
||||||
|
|
||||||
|
<TextBlock x:Name="VersionNumber" Grid.Row="0" Padding="0" Margin="0" |
||||||
|
FontSize="12" VerticalAlignment="Top" |
||||||
|
HorizontalAlignment="Right"/> |
||||||
|
|
||||||
|
<TextBlock x:Name="Time" Grid.Row="0" FontSize="78" |
||||||
|
VerticalAlignment="Stretch" HorizontalAlignment="Right" |
||||||
|
Text="{x:Bind _vm.CurrentTime, Mode=OneWay, FallbackValue=00}" |
||||||
|
Margin="0" Padding="0"/> |
||||||
|
|
||||||
|
<StackPanel Grid.Row="0" Orientation="Horizontal" |
||||||
|
VerticalAlignment="Top"> |
||||||
|
<Image Grid.Column="0" Width="88" Height="88" VerticalAlignment="Center" |
||||||
|
Source="Images\logo.png"/> |
||||||
|
<StackPanel Padding="8,0"> |
||||||
|
<TextBlock Text="Return to Ritherdon Project" FontSize="40"/> |
||||||
|
<StackPanel Orientation="Horizontal"> |
||||||
|
<TextBlock Text="Unnamed Project" Padding="0" FontSize="24" |
||||||
|
VerticalAlignment="Bottom"/> |
||||||
|
<TextBlock Text="by Nicola Ellis" Padding="0" Margin="12,0" |
||||||
|
FontSize="18" VerticalAlignment="Bottom"/> |
||||||
|
</StackPanel> |
||||||
|
</StackPanel> |
||||||
|
</StackPanel> |
||||||
|
|
||||||
|
<Grid Grid.Row="1" Margin="0,12"> |
||||||
|
|
||||||
|
<Grid.ColumnDefinitions> |
||||||
|
<ColumnDefinition Width="Auto"/> |
||||||
|
<ColumnDefinition Width="Auto"/> |
||||||
|
<ColumnDefinition Width="Auto"/> |
||||||
|
</Grid.ColumnDefinitions> |
||||||
|
|
||||||
|
<Grid.RowDefinitions> |
||||||
|
<RowDefinition Height="Auto"/> |
||||||
|
<RowDefinition Height="Auto"/> |
||||||
|
</Grid.RowDefinitions> |
||||||
|
|
||||||
|
<Grid x:Name="Factory1Grid" Grid.Row="0" Grid.Column="0" |
||||||
|
Background="{x:Bind _vm.Device1.StatusColour, Mode=OneWay, |
||||||
|
FallbackValue=Pink}" Margin="0,0,0,12" Width="300" Height="300"> |
||||||
|
<StackPanel Margin="12" VerticalAlignment="Stretch"> |
||||||
|
<TextBlock x:Name="Factory1Time" |
||||||
|
Text="{x:Bind _vm.Device1.LatestReading.time, |
||||||
|
Mode=OneWay, FallbackValue=404}" |
||||||
|
Foreground="White" FontSize="24"/> |
||||||
|
<TextBlock x:Name="Factory1Reading" |
||||||
|
Text="{x:Bind _vm.Device1.LatestReading.reading, |
||||||
|
Mode=OneWay, FallbackValue=404}" Foreground="White" |
||||||
|
VerticalAlignment="Bottom" FontSize="144"/> |
||||||
|
<TextBlock Text="Factory 1" Foreground="White" FontSize="36" |
||||||
|
VerticalAlignment="Bottom"/> |
||||||
|
</StackPanel> |
||||||
|
</Grid> |
||||||
|
|
||||||
|
<Grid x:Name="Factory2Grid" Grid.Row="0" Grid.Column="1" |
||||||
|
Background="{x:Bind _vm.Device2.StatusColour, Mode=OneWay, |
||||||
|
FallbackValue=Orange}" Margin="12,0,12,12" Width="300" Height="300"> |
||||||
|
<StackPanel Margin="12" VerticalAlignment="Stretch"> |
||||||
|
<TextBlock x:Name="Factory2Time" Foreground="White" FontSize="24" |
||||||
|
Text="{x:Bind _vm.Device2.LatestReading.time, |
||||||
|
Mode=OneWay, FallbackValue=404}" /> |
||||||
|
<TextBlock x:Name="Factory2Reading" |
||||||
|
Text="{x:Bind _vm.Device2.LatestReading.reading, |
||||||
|
Mode=OneWay, FallbackValue=404}" Foreground="White" |
||||||
|
VerticalAlignment="Bottom" FontSize="144"/> |
||||||
|
<TextBlock Text="Factory 2" Foreground="White" FontSize="36" |
||||||
|
VerticalAlignment="Bottom"/> |
||||||
|
</StackPanel> |
||||||
|
</Grid> |
||||||
|
|
||||||
|
<Grid Grid.Row="0" Grid.Column="2" Grid.RowSpan="2"> |
||||||
|
<StackPanel Orientation="Vertical"> |
||||||
|
<StackPanel Orientation="Horizontal"> |
||||||
|
<Rectangle Fill="LightSeaGreen" Width="92" Height="52"/> |
||||||
|
<TextBlock Text="Device is on" FontSize="42" |
||||||
|
VerticalAlignment="Center" Margin="12,0"/> |
||||||
|
</StackPanel> |
||||||
|
<StackPanel Orientation="Horizontal"> |
||||||
|
<Rectangle Fill="DarkSeaGreen" Width="92" Height="52"/> |
||||||
|
<TextBlock Text="Welding detected" FontSize="42" |
||||||
|
VerticalAlignment="Center" Margin="12,0"/> |
||||||
|
</StackPanel> |
||||||
|
<StackPanel Orientation="Horizontal"> |
||||||
|
<Rectangle Fill="LightSkyBlue" Width="92" Height="52"/> |
||||||
|
<TextBlock Text="Low light in factory" FontSize="42" |
||||||
|
VerticalAlignment="Center" Margin="12,0"/> |
||||||
|
</StackPanel> |
||||||
|
<StackPanel Orientation="Horizontal"> |
||||||
|
<Rectangle Fill="DarkOrange" Width="92" Height="52"/> |
||||||
|
<TextBlock Text="Unable to retrieve data" FontSize="42" |
||||||
|
VerticalAlignment="Center" Margin="12,0"/> |
||||||
|
</StackPanel> |
||||||
|
<StackPanel Orientation="Horizontal"> |
||||||
|
<Rectangle Fill="DarkRed" Width="92" Height="52"/> |
||||||
|
<TextBlock Text="Device is off" FontSize="42" |
||||||
|
VerticalAlignment="Center" Margin="12,0"/> |
||||||
|
</StackPanel> |
||||||
|
<TextBlock Text="Factory: 07:00 - 16:00" FontSize="42" |
||||||
|
VerticalAlignment="Center" Margin="0"/> |
||||||
|
<TextBlock Text="Gallery: 10:00 - 18:00" FontSize="42" |
||||||
|
VerticalAlignment="Center" Margin="0"/> |
||||||
|
<TextBlock Text="Dashboard updates at slower rate than devices." |
||||||
|
FontSize="18" Margin="0" Foreground="SlateGray" |
||||||
|
VerticalAlignment="Center"/> |
||||||
|
</StackPanel> |
||||||
|
|
||||||
|
</Grid> |
||||||
|
<!-- This device is not in use. Uncomment if becomes available. --> |
||||||
|
<!--<Grid x:Name="Factory3Grid" Grid.Row="0" Grid.Column="2" |
||||||
|
Background="{x:Bind _vm.Device3.StatusColour, Mode=OneWay, |
||||||
|
FallbackValue=Pink}" Margin="0,0,0,12" Width="300" Height="300"> |
||||||
|
<StackPanel Margin="12" VerticalAlignment="Stretch"> |
||||||
|
<TextBlock x:Name="Factory3Time" |
||||||
|
Text="{x:Bind _vm.Device3.LatestStatus.time, |
||||||
|
Mode=OneWay, FallbackValue=404}" |
||||||
|
Foreground="White" FontSize="24"/> |
||||||
|
<TextBlock x:Name="Factory3Reading" Foreground="White" |
||||||
|
Text="{x:Bind _vm.Device3.LatestReading.reading, |
||||||
|
Mode=OneWay, FallbackValue=404}" FontSize="144" |
||||||
|
VerticalAlignment="Bottom"/> |
||||||
|
<TextBlock Text="Factory 3" Foreground="White" FontSize="36" |
||||||
|
VerticalAlignment="Bottom"/> |
||||||
|
</StackPanel> |
||||||
|
</Grid>--> |
||||||
|
|
||||||
|
<Grid x:Name="Gallery1Grid" Grid.Row="1" Grid.Column="0" |
||||||
|
Background="{x:Bind _vm.Device4.StatusColour, Mode=OneWay, |
||||||
|
FallbackValue=Pink}" Margin="0,0,0,12" Width="300" Height="150"> |
||||||
|
<StackPanel Margin="12" VerticalAlignment="Bottom"> |
||||||
|
<TextBlock x:Name="Gallery1Time" Foreground="White" |
||||||
|
Text="{x:Bind _vm.Device4.LatestStatus.time, |
||||||
|
Mode=OneWay, FallbackValue=404}" FontSize="24"/> |
||||||
|
<TextBlock Text="Gallery 1" Foreground="White" FontSize="36" |
||||||
|
VerticalAlignment="Bottom"/> |
||||||
|
</StackPanel> |
||||||
|
<TextBlock Text="{x:Bind _vm.Device1.LatestReading.reading , |
||||||
|
Mode=OneWay, FallbackValue=404}" Foreground="White" |
||||||
|
HorizontalAlignment="Right" FontSize="16" |
||||||
|
VerticalAlignment="Bottom" Padding="4"/> |
||||||
|
</Grid> |
||||||
|
|
||||||
|
<Grid x:Name="Gallery2Grid" Grid.Row="1" Grid.Column="1" |
||||||
|
Background="{x:Bind _vm.Device5.StatusColour, Mode=OneWay, |
||||||
|
FallbackValue=Pink}" Margin="0,0,0,12" Width="300" Height="150"> |
||||||
|
<StackPanel Margin="12" VerticalAlignment="Bottom"> |
||||||
|
<TextBlock x:Name="Gallery2Time" Foreground="White" FontSize="24" |
||||||
|
Text="{x:Bind _vm.Device5.LatestStatus.time, |
||||||
|
Mode=OneWay, FallbackValue=404}" |
||||||
|
/> |
||||||
|
<TextBlock Text="Gallery 2" Foreground="White" FontSize="36" |
||||||
|
VerticalAlignment="Bottom"/> |
||||||
|
</StackPanel> |
||||||
|
<TextBlock Text="{x:Bind _vm.Device2.LatestReading.reading , |
||||||
|
Mode=OneWay, FallbackValue=404}" Foreground="White" |
||||||
|
HorizontalAlignment="Right" FontSize="16" |
||||||
|
VerticalAlignment="Bottom" Padding="4"/> |
||||||
|
</Grid> |
||||||
|
|
||||||
|
<!-- This device is not in use. Uncomment if becomes available. --> |
||||||
|
<!--<Grid x:Name="Gallery3Grid" Grid.Row="1" Grid.Column="2" |
||||||
|
Background="{x:Bind _vm.Device6.StatusColour, Mode=OneWay, |
||||||
|
FallbackValue=Pink}" Margin="0,0,0,12" Width="300" Height="150"> |
||||||
|
<StackPanel Margin="12" VerticalAlignment="Bottom"> |
||||||
|
<TextBlock x:Name="Gallery3Time" Foreground="White" FontSize="24" |
||||||
|
Text="{x:Bind _vm.Device6.LatestStatus.time, |
||||||
|
Mode=OneWay, FallbackValue=404}" /> |
||||||
|
<TextBlock Text="Gallery 3" Foreground="White" FontSize="36" |
||||||
|
VerticalAlignment="Bottom"/> |
||||||
|
</StackPanel> |
||||||
|
<TextBlock Text="{x:Bind _vm.Device3.LatestReading.reading , |
||||||
|
Mode=OneWay, FallbackValue=404}" Foreground="White" |
||||||
|
HorizontalAlignment="Right" FontSize="16" |
||||||
|
VerticalAlignment="Bottom" Padding="4"/> |
||||||
|
</Grid>--> |
||||||
|
|
||||||
|
</Grid> |
||||||
|
|
||||||
|
<Grid Grid.Row="2" Margin="0"> |
||||||
|
|
||||||
|
<Grid.ColumnDefinitions> |
||||||
|
<ColumnDefinition Width="Auto"/> |
||||||
|
<ColumnDefinition Width="*" MinWidth="350"/> |
||||||
|
<ColumnDefinition Width="Auto"/> |
||||||
|
</Grid.ColumnDefinitions> |
||||||
|
|
||||||
|
<HyperlinkButton x:Name="InfoButton" Grid.Column="0" |
||||||
|
NavigateUri="http://www.nicolaellis.com" |
||||||
|
FontFamily="Segoe MDL2 Assets" Content="" |
||||||
|
Height="79" Width="79" VerticalAlignment="Center" |
||||||
|
HorizontalAlignment="Left" FontSize="28" |
||||||
|
ToolTipService.Placement="Mouse" |
||||||
|
ToolTipService.ToolTip="This is a link to a webpage with information about Nicola and the project."/> |
||||||
|
|
||||||
|
<TextBox x:Name="WebAddressBox" Grid.Column="1" FontSize="26" |
||||||
|
Text="{x:Bind _vm.BaseURL , Mode=TwoWay}" |
||||||
|
Padding="20" TextAlignment="Left" |
||||||
|
HorizontalAlignment="Stretch" TextWrapping="NoWrap" |
||||||
|
Margin="0" VerticalAlignment="Center" |
||||||
|
HorizontalContentAlignment="Left" |
||||||
|
ToolTipService.Placement="Mouse" |
||||||
|
ToolTipService.ToolTip="The base U.R.L. used to form the A.P.I. queries." |
||||||
|
PlaceholderText="Enter the base U.R.L. here..." /> |
||||||
|
|
||||||
|
<StackPanel Orientation="Horizontal" Grid.Column="2"> |
||||||
|
<ToggleButton x:Name="PlayButton" FontFamily="Segoe MDL2 Assets" |
||||||
|
Content="" Height="79" Width="79" |
||||||
|
VerticalAlignment="Center" FontSize="28" |
||||||
|
Margin="0,0,12,0" ToolTipService.Placement="Mouse" |
||||||
|
IsChecked="False" Unchecked="PlayButton_Unchecked" |
||||||
|
Checked="PlayButton_Checked" |
||||||
|
ToolTipService.ToolTip="Click to pause the service. It will give the server a moment before it starts receiving requests from this app. again."/> |
||||||
|
<Button x:Name="SaveURLButton" FontFamily="Segoe MDL2 Assets" |
||||||
|
Content="" Height="79" Width="79" |
||||||
|
VerticalAlignment="Center" FontSize="28" |
||||||
|
Click="SaveURLButton_Click" |
||||||
|
ToolTipService.Placement="Mouse" |
||||||
|
ToolTipService.ToolTip="Click to save the base U.R.L."/> |
||||||
|
</StackPanel> |
||||||
|
|
||||||
|
</Grid> |
||||||
|
|
||||||
|
</Grid> |
||||||
|
</Page> |
@ -0,0 +1,80 @@ |
|||||||
|
using EyesAndEars.UWP.Services; |
||||||
|
using EyesAndEars.UWP.ViewModels; |
||||||
|
using System; |
||||||
|
using Windows.ApplicationModel; |
||||||
|
using Windows.UI.Xaml; |
||||||
|
using Windows.UI.Xaml.Controls; |
||||||
|
|
||||||
|
namespace EyesAndEars.UWP { |
||||||
|
|
||||||
|
public sealed partial class MainPage : Page { |
||||||
|
|
||||||
|
MainPageVM _vm = new MainPageVM(); |
||||||
|
DispatcherTimer _dispatcherTimer = new DispatcherTimer(); |
||||||
|
|
||||||
|
public MainPage() { |
||||||
|
InitializeComponent(); |
||||||
|
IntialiseDataContext(); |
||||||
|
SetVersionNumber(); |
||||||
|
IntialiseRefreshTime(); |
||||||
|
} |
||||||
|
|
||||||
|
void SetVersionNumber() { |
||||||
|
var package = Package.Current; |
||||||
|
var packageId = package.Id; |
||||||
|
var version = packageId.Version; |
||||||
|
VersionNumber.Text = $"Ver: {version.Major}.{version.Minor}.{version.Build}.{version.Revision}"; |
||||||
|
} |
||||||
|
|
||||||
|
async void IntialiseDataContext() { |
||||||
|
// Device 3 and 6 are not in use. |
||||||
|
_vm.BaseURL = await DataServices.GetBaseURLAsync(); |
||||||
|
_vm.Device1 = DataServices.CreateFallBackDevice(1); |
||||||
|
_vm.Device2 = DataServices.CreateFallBackDevice(2); |
||||||
|
// _vm.Device3 = DataServices.CreateFallBackDevice(3); |
||||||
|
_vm.Device4 = DataServices.CreateFallBackDevice(4); |
||||||
|
_vm.Device5 = DataServices.CreateFallBackDevice(5); |
||||||
|
// _vm.Device6 = DataServices.CreateFallBackDevice(6); |
||||||
|
_vm.CurrentTime = DateTime.UtcNow.ToShortTimeString(); |
||||||
|
DataContext = _vm; |
||||||
|
} |
||||||
|
|
||||||
|
void IntialiseRefreshTime() { |
||||||
|
// TimeSpan Intervals: Days, Hours, Minutes, Seconds, Milliseconds. |
||||||
|
_dispatcherTimer.Interval = new TimeSpan(0, 0, 0, 1, 0); |
||||||
|
_dispatcherTimer.Tick += UpdateViewModel; |
||||||
|
_dispatcherTimer.Start(); |
||||||
|
} |
||||||
|
|
||||||
|
async void UpdateViewModel(object sender, object e) { |
||||||
|
var url = _vm.BaseURL; |
||||||
|
if (!string.IsNullOrEmpty(url)) { |
||||||
|
// Devices 3 and 6 are not in use. |
||||||
|
_vm.Device1 = await DataServices.UpdateDevice(url, 1); |
||||||
|
_vm.Device2 = await DataServices.UpdateDevice(url, 2); |
||||||
|
// _vm.Device3 = await DataServices.UpdateDevice(url, 3); |
||||||
|
_vm.Device4 = await DataServices.UpdateDevice(url, 4); |
||||||
|
_vm.Device5 = await DataServices.UpdateDevice(url, 5); |
||||||
|
// _vm.Device6 = await DataServices.UpdateDevice(url, 6); |
||||||
|
_vm.CurrentTime = DateTime.UtcNow.ToShortTimeString(); |
||||||
|
} |
||||||
|
else { |
||||||
|
IntialiseDataContext(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
async void SaveURLButton_Click(object sender, RoutedEventArgs e) { |
||||||
|
await DataServices.SaveBaseURLAsync(WebAddressBox.Text); |
||||||
|
} |
||||||
|
|
||||||
|
void PlayButton_Checked(object sender, RoutedEventArgs e) { |
||||||
|
PlayButton.Content = "\uE768"; |
||||||
|
_dispatcherTimer.Stop(); |
||||||
|
} |
||||||
|
|
||||||
|
void PlayButton_Unchecked(object sender, RoutedEventArgs e) { |
||||||
|
PlayButton.Content = "\uE71A"; |
||||||
|
_dispatcherTimer.Start(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,25 @@ |
|||||||
|
using Windows.UI.Xaml.Media; |
||||||
|
|
||||||
|
namespace EyesAndEars.UWP.Models { |
||||||
|
public class Device { |
||||||
|
|
||||||
|
public int Id { get; set; } |
||||||
|
|
||||||
|
public LightReading LatestReading { get; set; } |
||||||
|
|
||||||
|
public DeviceStatus LatestStatus { get; set; } |
||||||
|
|
||||||
|
public SolidColorBrush StatusColour { get; set; } |
||||||
|
|
||||||
|
public Device() { } |
||||||
|
|
||||||
|
public Device(int id, LightReading reading, DeviceStatus status, |
||||||
|
SolidColorBrush colour) { |
||||||
|
|
||||||
|
Id = id; |
||||||
|
LatestReading = reading; |
||||||
|
LatestStatus = status; |
||||||
|
StatusColour = colour; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
namespace EyesAndEars.UWP.Models { |
||||||
|
|
||||||
|
public class DeviceStatus { |
||||||
|
public int id { get; set; } |
||||||
|
public string status { get; set; } |
||||||
|
public DateTime time { get; set; } |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,12 @@ |
|||||||
|
using System; |
||||||
|
|
||||||
|
namespace EyesAndEars.UWP.Models { |
||||||
|
|
||||||
|
public class LightReading { |
||||||
|
|
||||||
|
public int id { get; set; } |
||||||
|
public int reading { get; set; } |
||||||
|
public DateTime time { get; set; } |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,55 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
|
||||||
|
<Package |
||||||
|
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" |
||||||
|
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" |
||||||
|
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" |
||||||
|
IgnorableNamespaces="uap mp"> |
||||||
|
|
||||||
|
<Identity |
||||||
|
Name="55acd946-60d4-4776-b6c6-03fef750e3da" |
||||||
|
Publisher="CN=Craig Oates" |
||||||
|
Version="2020.1.14.0" /> |
||||||
|
|
||||||
|
<mp:PhoneIdentity PhoneProductId="55acd946-60d4-4776-b6c6-03fef750e3da" PhonePublisherId="00000000-0000-0000-0000-000000000000"/> |
||||||
|
|
||||||
|
<Properties> |
||||||
|
<DisplayName>EyesAndEars.UWP</DisplayName> |
||||||
|
<PublisherDisplayName>Craig Oates</PublisherDisplayName> |
||||||
|
<Logo>Assets\StoreLogo.png</Logo> |
||||||
|
</Properties> |
||||||
|
|
||||||
|
<Dependencies> |
||||||
|
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" /> |
||||||
|
</Dependencies> |
||||||
|
|
||||||
|
<Resources> |
||||||
|
<Resource Language="x-generate"/> |
||||||
|
</Resources> |
||||||
|
|
||||||
|
<Applications> |
||||||
|
<Application Id="App" |
||||||
|
Executable="$targetnametoken$.exe" |
||||||
|
EntryPoint="EyesAndEars.UWP.App"> |
||||||
|
<uap:VisualElements |
||||||
|
DisplayName="Eyes and Ears" |
||||||
|
Square150x150Logo="Assets\Square150x150Logo.png" |
||||||
|
Square44x44Logo="Assets\Square44x44Logo.png" |
||||||
|
Description="A dashboard for monitoring the unname, at time of writing, project which is part of the Return to Ritherdon Project ." |
||||||
|
BackgroundColor="transparent"> |
||||||
|
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" Square71x71Logo="Assets\SmallTile.png" Square310x310Logo="Assets\LargeTile.png"> |
||||||
|
<uap:ShowNameOnTiles> |
||||||
|
<uap:ShowOn Tile="square150x150Logo"/> |
||||||
|
<uap:ShowOn Tile="wide310x150Logo"/> |
||||||
|
<uap:ShowOn Tile="square310x310Logo"/> |
||||||
|
</uap:ShowNameOnTiles> |
||||||
|
</uap:DefaultTile > |
||||||
|
<uap:SplashScreen Image="Assets\SplashScreen.png" /> |
||||||
|
</uap:VisualElements> |
||||||
|
</Application> |
||||||
|
</Applications> |
||||||
|
|
||||||
|
<Capabilities> |
||||||
|
<Capability Name="internetClient" /> |
||||||
|
</Capabilities> |
||||||
|
</Package> |
@ -0,0 +1,28 @@ |
|||||||
|
using System.Reflection; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following |
||||||
|
// set of attributes. Change these attribute values to modify the information |
||||||
|
// associated with an assembly. |
||||||
|
[assembly: AssemblyTitle("EyesAndEars.UWP")] |
||||||
|
[assembly: AssemblyDescription("")] |
||||||
|
[assembly: AssemblyConfiguration("")] |
||||||
|
[assembly: AssemblyCompany("")] |
||||||
|
[assembly: AssemblyProduct("EyesAndEars.UWP")] |
||||||
|
[assembly: AssemblyCopyright("Copyright © 2020")] |
||||||
|
[assembly: AssemblyTrademark("")] |
||||||
|
[assembly: AssemblyCulture("")] |
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values: |
||||||
|
// |
||||||
|
// Major Version |
||||||
|
// Minor Version |
||||||
|
// Build Number |
||||||
|
// Revision |
||||||
|
// |
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers |
||||||
|
// by using the '*' as shown below: |
||||||
|
// [assembly: AssemblyVersion("1.0.*")] |
||||||
|
[assembly: AssemblyVersion("1.0.0.0")] |
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")] |
||||||
|
[assembly: ComVisible(false)] |
@ -0,0 +1,50 @@ |
|||||||
|
<!-- |
||||||
|
This file contains Runtime Directives used by .NET Native. The defaults here are suitable for most |
||||||
|
developers. However, you can modify these parameters to modify the behavior of the .NET Native |
||||||
|
optimizer. |
||||||
|
|
||||||
|
Runtime Directives are documented at https://go.microsoft.com/fwlink/?LinkID=391919 |
||||||
|
|
||||||
|
To fully enable reflection for App1.MyClass and all of its public/private members |
||||||
|
<Type Name="App1.MyClass" Dynamic="Required All"/> |
||||||
|
|
||||||
|
To enable dynamic creation of the specific instantiation of AppClass<T> over System.Int32 |
||||||
|
<TypeInstantiation Name="App1.AppClass" Arguments="System.Int32" Activate="Required Public" /> |
||||||
|
|
||||||
|
Using the Namespace directive to apply reflection policy to all the types in a particular namespace |
||||||
|
<Namespace Name="DataClasses.ViewModels" Serialize="All" /> |
||||||
|
--> |
||||||
|
|
||||||
|
<Directives xmlns="http://schemas.microsoft.com/netfx/2013/01/metadata"> |
||||||
|
<Application> |
||||||
|
<!-- |
||||||
|
An Assembly element with Name="*Application*" applies to all assemblies in |
||||||
|
the application package. The asterisks are not wildcards. |
||||||
|
--> |
||||||
|
<Assembly Name="*Application*" Dynamic="Required All" /> |
||||||
|
|
||||||
|
|
||||||
|
<!-- Add your application specific runtime directives here. --> |
||||||
|
|
||||||
|
<!-- Note: The Inclusion of the JSON Serialization Converters. |
||||||
|
=========================================================================== |
||||||
|
The Json.Serialization converts are needed so the app. can operate as "release". |
||||||
|
Without them, the app. throw a System.Reflection.MissingMetadataException |
||||||
|
when you try and run the app. using the "release" compiler setting. |
||||||
|
I added the lines of code below based on the Issue raised and discussed on |
||||||
|
GitHub. The link is https://github.com/dotnet/runtime/issues/978. |
||||||
|
--> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterString" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterUri" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterBoolean" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterInt32" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterInt16" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterByte" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterDecimal" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterGuid" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterEnum" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterDateTime" Dynamic="Required All" /> |
||||||
|
<Type Name="System.Text.Json.Serialization.Converters.JsonConverterDateTimeOffset" Dynamic="Required All" /> |
||||||
|
|
||||||
|
</Application> |
||||||
|
</Directives> |
@ -0,0 +1,175 @@ |
|||||||
|
using EyesAndEars.UWP.Models; |
||||||
|
using System; |
||||||
|
using System.Diagnostics; |
||||||
|
using System.Text.Json; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using Windows.Storage; |
||||||
|
using Windows.UI; |
||||||
|
using Windows.UI.Xaml.Media; |
||||||
|
|
||||||
|
namespace EyesAndEars.UWP.Services { |
||||||
|
public static class DataServices { |
||||||
|
|
||||||
|
public static async Task<Device> UpdateDevice(string url, int deviceId) { |
||||||
|
try { |
||||||
|
var id = MapFactoryDeviceToGalleyDevice(deviceId); // Has note. |
||||||
|
var readingAPI = $"{url}/api/readings/latest/{id}"; |
||||||
|
var statusAPI = $"{url}/api/status/latest/{deviceId}"; |
||||||
|
var readingJSON = await WebServices.GetJSON(readingAPI); |
||||||
|
var statusJSON = await WebServices.GetJSON(statusAPI); |
||||||
|
var r = MapToLightReading(readingJSON); |
||||||
|
var s = MapToDeviceStatus(statusJSON); |
||||||
|
var c = UpdateStatusColour(s.status, r.reading); |
||||||
|
return new Device(deviceId, r, s, c); |
||||||
|
} |
||||||
|
catch (Exception e) { |
||||||
|
Debug.WriteLine(e.Message); |
||||||
|
return CreateFallBackDevice(deviceId); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static SolidColorBrush UpdateStatusColour(string status, int reading) { |
||||||
|
try { |
||||||
|
if (status.Equals("on", StringComparison.OrdinalIgnoreCase)) { |
||||||
|
/* Note: Reading values breakdown. |
||||||
|
* ======================================= |
||||||
|
* 1. When testing the light meters, the base line for normal |
||||||
|
* light is 48 or below. Anything above this is when one of |
||||||
|
* the guys in the factory was welding. Becuase of this, |
||||||
|
* I have set 0 to 48 as the 'default' status on the |
||||||
|
* dashboard. |
||||||
|
* |
||||||
|
* 2. During testing we noticed the light meters would |
||||||
|
* return 'negative light' values. There is a reason for |
||||||
|
* this but that is out of the scope of this project. This |
||||||
|
* project just needs to process the data. The negative |
||||||
|
* light values are when the lights in the factory are off. |
||||||
|
* The light meter is still running but there is no light |
||||||
|
* to measure. So, everything is fine but it looks broken. |
||||||
|
* The 'LightSkyBlue' colour is used to help relay this |
||||||
|
* bit of information. |
||||||
|
*/ |
||||||
|
if (reading > 0 && reading < 48) // On but no weld detected. |
||||||
|
return new SolidColorBrush(Colors.LightSeaGreen); |
||||||
|
if (reading > 48) // On and weld detected. |
||||||
|
return new SolidColorBrush(Colors.DarkSeaGreen); |
||||||
|
else { |
||||||
|
// On but factory lights are off. |
||||||
|
return new SolidColorBrush(Colors.LightSkyBlue); |
||||||
|
} |
||||||
|
} |
||||||
|
else return new SolidColorBrush(Colors.DarkRed); } |
||||||
|
catch (Exception e) { |
||||||
|
Debug.WriteLine(e.Message); |
||||||
|
return new SolidColorBrush(Colors.DarkOrange); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* Note: The Purpose of Mapping a Factory to a Gallery Device. |
||||||
|
* ================================================================ |
||||||
|
* Every device in the project is paired up with another. |
||||||
|
* Factory1 => Gallery1 | Device1 => Device4 |
||||||
|
* Factory2 => Gallery2 | Device2 => Device5 |
||||||
|
* Factory3 => Gallery3 | Device3 => Device6 (Note in use at this time) |
||||||
|
* At the moment, when a device completes a status update, each one |
||||||
|
* is ran throught the "UpdateDevice" function (above). This means |
||||||
|
* the latest light reading for a light meter (factory) must be |
||||||
|
* retrieved when a galley-based device's status is updated. |
||||||
|
* From a strict point-of-view, the gallery device does not need it |
||||||
|
* so I should/could seperate out this functionality into seperate |
||||||
|
* functions. For now though, a light reading is still needed to be |
||||||
|
* retrieved because of the way the functions are called. |
||||||
|
* This function just maps/pairs the (factory) light reading to the |
||||||
|
* appropriate gallery device. By doing this, the gallery device |
||||||
|
* has extra information on its paired up light meter. One way I |
||||||
|
* have used that information is to show a small piece of text in |
||||||
|
* the gallery status box to quickly check the accuracy of the |
||||||
|
* synchronisation between the factory and gallery devices. |
||||||
|
*/ |
||||||
|
static int MapFactoryDeviceToGalleyDevice(int deviceId) { |
||||||
|
int id = 0; |
||||||
|
if (deviceId > 3) { |
||||||
|
switch (deviceId) { |
||||||
|
case 4: |
||||||
|
id = 1; |
||||||
|
break; |
||||||
|
case 5: |
||||||
|
id = 2; |
||||||
|
break; |
||||||
|
case 6: |
||||||
|
id = 3; |
||||||
|
break; |
||||||
|
default: |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
id = deviceId; |
||||||
|
} |
||||||
|
return id; |
||||||
|
} |
||||||
|
|
||||||
|
static LightReading MapToLightReading(string json) { |
||||||
|
try { |
||||||
|
var reading = JsonSerializer.Deserialize<LightReading>(json); |
||||||
|
return reading; |
||||||
|
} |
||||||
|
catch (Exception e) { |
||||||
|
Debug.WriteLine(e.Message); |
||||||
|
return CreateDefaultLightReading(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static DeviceStatus MapToDeviceStatus(string json) { |
||||||
|
try { |
||||||
|
var status = JsonSerializer.Deserialize<DeviceStatus>(json); |
||||||
|
return status; |
||||||
|
} |
||||||
|
catch (Exception e) { |
||||||
|
Debug.WriteLine(e.Message); |
||||||
|
return CreateDefaultDeviceStatus(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static Device CreateFallBackDevice(int deviceId) { |
||||||
|
// "999" and "err" are acting as sentinals in this context. |
||||||
|
var r = new LightReading { id = 0, reading = 999, time = DateTime.Now }; |
||||||
|
var s = new DeviceStatus { id = 0, status = "err", time = DateTime.Now }; |
||||||
|
var c = new SolidColorBrush(Colors.DarkOrange); |
||||||
|
var d = new Device(deviceId, r, s, c); |
||||||
|
return d; |
||||||
|
} |
||||||
|
|
||||||
|
static LightReading CreateDefaultLightReading() => |
||||||
|
new LightReading { id = 0, reading = 999, time = DateTime.Now }; |
||||||
|
|
||||||
|
static DeviceStatus CreateDefaultDeviceStatus() => |
||||||
|
new DeviceStatus { id = 0, status = "err", time = DateTime.Now }; |
||||||
|
|
||||||
|
public static async Task SaveBaseURLAsync(string contents) { |
||||||
|
try { |
||||||
|
var storageFolder = ApplicationData.Current.LocalFolder; |
||||||
|
var baseURLFile = await storageFolder.CreateFileAsync("baseURL.txt", |
||||||
|
CreationCollisionOption.ReplaceExisting); |
||||||
|
await FileIO.WriteTextAsync(baseURLFile, contents); |
||||||
|
} |
||||||
|
catch (Exception e) { |
||||||
|
Debug.WriteLine(e.Message); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static async Task<string> GetBaseURLAsync() { |
||||||
|
try { |
||||||
|
var storageFolder = ApplicationData.Current.LocalFolder; |
||||||
|
var baseURLFile = await storageFolder.GetFileAsync("baseURL.txt"); |
||||||
|
var text = await FileIO.ReadTextAsync(baseURLFile); |
||||||
|
return text; |
||||||
|
} |
||||||
|
catch (Exception e) { |
||||||
|
Debug.WriteLine(e.Message); |
||||||
|
return ""; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,20 @@ |
|||||||
|
using System.Net.Http; |
||||||
|
using System.Net.Http.Headers; |
||||||
|
using System.Threading.Tasks; |
||||||
|
|
||||||
|
namespace EyesAndEars.UWP.Services { |
||||||
|
public static class WebServices { |
||||||
|
|
||||||
|
private static readonly HttpClient _client = new HttpClient(); |
||||||
|
|
||||||
|
public static async Task<string> GetJSON(string url) { |
||||||
|
_client.DefaultRequestHeaders.Accept.Clear(); |
||||||
|
var response = await _client.GetAsync(url); |
||||||
|
_client.DefaultRequestHeaders.Accept.Add( |
||||||
|
new MediaTypeWithQualityHeaderValue("application/json")); |
||||||
|
var result = await _client.GetStringAsync(url); |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,127 @@ |
|||||||
|
using EyesAndEars.UWP.Models; |
||||||
|
using System; |
||||||
|
using System.ComponentModel; |
||||||
|
|
||||||
|
namespace EyesAndEars.UWP.ViewModels { |
||||||
|
public class MainPageVM : INotifyPropertyChanged { |
||||||
|
|
||||||
|
/* Note: Why I did not use a collection of some sort and hard-coded the |
||||||
|
* objects instead. |
||||||
|
* ==================================================================== |
||||||
|
* Because the projects requirements are fixed in-place and this |
||||||
|
* program does not have long-term requirements, I decided to not worry |
||||||
|
* about long-term maintenance benefits. If something comes from this |
||||||
|
* project afterwards, the duplicated nature of the code below will |
||||||
|
* probably need refacorting but I will leave that to the person |
||||||
|
* needing to make that call at that time. |
||||||
|
*/ |
||||||
|
|
||||||
|
public MainPageVM() { } |
||||||
|
|
||||||
|
public MainPageVM(Device f1, Device f2, Device f3, |
||||||
|
Device g1, Device g2, Device g3) { |
||||||
|
Device1 = f1; |
||||||
|
Device2 = f2; |
||||||
|
Device3 = f3; |
||||||
|
Device4 = g1; |
||||||
|
Device5 = g2; |
||||||
|
Device6 = g3; |
||||||
|
CurrentTime = DateTime.Now.ToShortTimeString(); |
||||||
|
} |
||||||
|
|
||||||
|
string _currentTime; |
||||||
|
|
||||||
|
public string CurrentTime { |
||||||
|
get { return _currentTime; } |
||||||
|
set { |
||||||
|
if (value != _currentTime) { |
||||||
|
_currentTime = value; |
||||||
|
NotifyPropertyChanged("CurrentTime"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
string _baseURL; |
||||||
|
public string BaseURL { |
||||||
|
get { return _baseURL; } |
||||||
|
set { |
||||||
|
if (value != _baseURL) { |
||||||
|
_baseURL = value; |
||||||
|
NotifyPropertyChanged("BaseURL"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Device _device1; |
||||||
|
public Device Device1 { |
||||||
|
get { return _device1; } |
||||||
|
set { |
||||||
|
if (value != _device1) { |
||||||
|
_device1 = value; |
||||||
|
NotifyPropertyChanged("Device1"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Device _device2; |
||||||
|
public Device Device2 { |
||||||
|
get { return _device2; } |
||||||
|
set { |
||||||
|
if (value != _device2) { |
||||||
|
_device2 = value; |
||||||
|
NotifyPropertyChanged("Device2"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Device _device3; |
||||||
|
public Device Device3 { |
||||||
|
get { return _device3; } |
||||||
|
set { |
||||||
|
if (value != _device3) { |
||||||
|
_device3 = value; |
||||||
|
NotifyPropertyChanged("Device3"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Device _device4; |
||||||
|
public Device Device4 { |
||||||
|
get { return _device4; } |
||||||
|
set { |
||||||
|
if (value != _device4) { |
||||||
|
_device4 = value; |
||||||
|
NotifyPropertyChanged("Device4"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Device _device5; |
||||||
|
public Device Device5 { |
||||||
|
get { return _device5; } |
||||||
|
set { |
||||||
|
if (value != _device5) { |
||||||
|
_device5 = value; |
||||||
|
NotifyPropertyChanged("Device5"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
Device _device6; |
||||||
|
public Device Device6 { |
||||||
|
get { return _device6; } |
||||||
|
set { |
||||||
|
if (value != _device6) { |
||||||
|
_device6 = value; |
||||||
|
NotifyPropertyChanged("Device6"); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public event PropertyChangedEventHandler PropertyChanged; |
||||||
|
|
||||||
|
protected void NotifyPropertyChanged(string info) { |
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(info)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 30 KiB |