mvvm pattern
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
using System;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Toolkit.Mvvm.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@@ -39,6 +41,15 @@ namespace BlueControl.uwp
|
||||
/// <param name="e">Details about the launch request and process.</param>
|
||||
protected override void OnLaunched(LaunchActivatedEventArgs e)
|
||||
{
|
||||
|
||||
Ioc.Default.ConfigureServices(
|
||||
new ServiceCollection()
|
||||
.AddSingleton<Services.IShellService, Services.UiShellService>((input) => new Services.UiShellService(Window.Current.Dispatcher))
|
||||
.AddSingleton<Services.IBluetoothService, Services.BluetoothService>()
|
||||
.BuildServiceProvider());
|
||||
|
||||
|
||||
|
||||
Frame rootFrame = Window.Current.Content as Frame;
|
||||
|
||||
// Do not repeat app initialization when the Window already has content,
|
||||
|
||||
@@ -123,6 +123,10 @@
|
||||
<DependentUpon>MainPage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Services\BluetoothService.cs" />
|
||||
<Compile Include="Services\IBluetoothService.cs" />
|
||||
<Compile Include="Services\IShellService.cs" />
|
||||
<Compile Include="Services\UiShellService.cs" />
|
||||
<Compile Include="ViewModels\MainPageViewModel.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
@@ -151,9 +155,21 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection">
|
||||
<Version>6.0.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform">
|
||||
<Version>6.2.12</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Toolkit.Mvvm">
|
||||
<Version>7.1.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Xaml.Behaviors.Uwp.Managed">
|
||||
<Version>2.0.1</Version>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Folder Include="Views\" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Condition=" '$(VisualStudioVersion)' == '' or '$(VisualStudioVersion)' < '14.0' ">
|
||||
<VisualStudioVersion>14.0</VisualStudioVersion>
|
||||
|
||||
@@ -6,7 +6,20 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
xmlns:viewModels="using:BlueControl.uwp.ViewModels"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:core="using:Microsoft.Xaml.Interactions.Core"
|
||||
>
|
||||
<Page.DataContext>
|
||||
<viewModels:MainPageViewModel x:Name="ViewModel"/>
|
||||
</Page.DataContext>
|
||||
<interactivity:Interaction.Behaviors>
|
||||
<core:EventTriggerBehavior EventName="Loaded">
|
||||
<core:InvokeCommandAction Command="{x:Bind ViewModel.ReloadCommand}"/>
|
||||
</core:EventTriggerBehavior>
|
||||
</interactivity:Interaction.Behaviors>
|
||||
|
||||
|
||||
<Grid>
|
||||
<TextBlock Text="{Binding Text}" FontSize="40" TextAlignment="Center" VerticalAlignment="Center"></TextBlock>
|
||||
|
||||
@@ -28,13 +28,13 @@ namespace BlueControl.uwp
|
||||
/// </summary>
|
||||
public sealed partial class MainPage : Page
|
||||
{
|
||||
private ViewModels.MainPageViewModel vm = new ViewModels.MainPageViewModel();
|
||||
//private ViewModels.MainPageViewModel vm = new ViewModels.MainPageViewModel();
|
||||
public MainPage()
|
||||
{
|
||||
this.vm.StaDispatcher = this.Dispatcher;
|
||||
this.DataContext = vm;
|
||||
//this.vm.StaDispatcher = this.Dispatcher;
|
||||
//this.DataContext = vm;
|
||||
this.InitializeComponent();
|
||||
this.Loading += async (sender, args) => await vm.ReloadAsync();
|
||||
//this.Loading += async (sender, args) => await vm.ReloadAsync();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
89
src/BlueControl.uwp/Services/BluetoothService.cs
Normal file
89
src/BlueControl.uwp/Services/BluetoothService.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Devices.Bluetooth;
|
||||
using Windows.Devices.Bluetooth.Advertisement;
|
||||
using Windows.Devices.Enumeration;
|
||||
|
||||
namespace BlueControl.uwp.Services
|
||||
{
|
||||
public class BluetoothService : IBluetoothService
|
||||
{
|
||||
private bool control = false;
|
||||
public BluetoothService()
|
||||
{
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
private BluetoothLEAdvertisementWatcher bleWatcher = null;
|
||||
public async Task<bool> IsConnectedAsync(string deviceName)
|
||||
{
|
||||
return (from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromConnectionStatus(BluetoothConnectionStatus.Connected)) where x.Name == deviceName select x).Any();
|
||||
}
|
||||
|
||||
public async Task<bool> IsPairedAsync(string deviceName)
|
||||
{
|
||||
return (from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true)) where x.Name == deviceName select x).Any();
|
||||
}
|
||||
|
||||
public async Task UnpairAsync(string deviceName)
|
||||
{
|
||||
var device = (from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true)) where x.Name == deviceName select x).FirstOrDefault();
|
||||
if (device != null)
|
||||
await device.Pairing.UnpairAsync();
|
||||
}
|
||||
|
||||
private Action<string> pinCreatedCallBack = null;
|
||||
private void Custom_PairingRequested(DeviceInformationCustomPairing sender, DevicePairingRequestedEventArgs args)
|
||||
{
|
||||
|
||||
if (this.pinCreatedCallBack != null) pinCreatedCallBack(args.Pin);
|
||||
args.Accept(args.Pin);
|
||||
}
|
||||
|
||||
public async Task StartAutoPairingAsync(string deviceName, Action onFoundTryingToPair, Action<string> onPinCreated, Action onSuccess, Action onError)
|
||||
{
|
||||
pinCreatedCallBack = onPinCreated;
|
||||
|
||||
if (this.bleWatcher == null)
|
||||
{
|
||||
this.bleWatcher = new BluetoothLEAdvertisementWatcher();
|
||||
this.bleWatcher.Received += async (sender, args) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!args.IsConnectable || control == true) return;
|
||||
control = true;
|
||||
var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
|
||||
if (dev.Name == deviceName && dev.DeviceInformation.Pairing.CanPair)
|
||||
{
|
||||
if (onFoundTryingToPair != null) onFoundTryingToPair();
|
||||
|
||||
System.Threading.Thread.Sleep(3000);
|
||||
dev.DeviceInformation.Pairing.Custom.PairingRequested += Custom_PairingRequested;
|
||||
var t = await dev.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.DisplayPin, DevicePairingProtectionLevel.Encryption);
|
||||
if (t.Status == DevicePairingResultStatus.Paired)
|
||||
{
|
||||
this.bleWatcher.Stop();
|
||||
if (onSuccess != null) onSuccess();
|
||||
}
|
||||
else
|
||||
if (onError != null) onError();
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
control = false;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
this.bleWatcher.Start();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
18
src/BlueControl.uwp/Services/IBluetoothService.cs
Normal file
18
src/BlueControl.uwp/Services/IBluetoothService.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BlueControl.uwp.Services
|
||||
{
|
||||
public interface IBluetoothService
|
||||
{
|
||||
Task<bool> IsConnectedAsync(string deviceName);
|
||||
Task<bool> IsPairedAsync(string deviceName);
|
||||
Task UnpairAsync(string deviceName);
|
||||
Task StartAutoPairingAsync(string deviceName, Action onFoundTryingToPair, Action<string> onPinCreated, Action onSuccess, Action onError);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
14
src/BlueControl.uwp/Services/IShellService.cs
Normal file
14
src/BlueControl.uwp/Services/IShellService.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BlueControl.uwp.Services
|
||||
{
|
||||
public interface IShellService
|
||||
{
|
||||
Task UiStaRunAsync(Action action);
|
||||
void CloseApplication();
|
||||
}
|
||||
}
|
||||
30
src/BlueControl.uwp/Services/UiShellService.cs
Normal file
30
src/BlueControl.uwp/Services/UiShellService.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BlueControl.uwp.Services
|
||||
{
|
||||
public class UiShellService : IShellService
|
||||
{
|
||||
public async Task UiStaRunAsync(Action action)
|
||||
{
|
||||
if (StaDispatcher != null)
|
||||
await StaDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => action());
|
||||
}
|
||||
|
||||
public Windows.UI.Core.CoreDispatcher StaDispatcher { get; set; }
|
||||
|
||||
public UiShellService(Windows.UI.Core.CoreDispatcher dispacher)
|
||||
{
|
||||
this.StaDispatcher = dispacher;
|
||||
}
|
||||
|
||||
public void CloseApplication()
|
||||
{
|
||||
App.Current.Exit();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,12 @@
|
||||
using System;
|
||||
using Microsoft.Toolkit.Mvvm.DependencyInjection;
|
||||
using Microsoft.Toolkit.Mvvm.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Windows.Devices.Bluetooth;
|
||||
using Windows.Devices.Bluetooth.Advertisement;
|
||||
using Windows.Devices.Enumeration;
|
||||
@@ -14,22 +17,18 @@ namespace BlueControl.uwp.ViewModels
|
||||
public class MainPageViewModel : INotifyPropertyChanged
|
||||
{
|
||||
private const string SURFACE_KEYBOARD_NAME = "Surface Keyboard";
|
||||
private readonly BluetoothLEAdvertisementWatcher bleWatcher = new BluetoothLEAdvertisementWatcher();
|
||||
private bool control = false;
|
||||
public Windows.UI.Core.CoreDispatcher StaDispatcher { get; set; }
|
||||
|
||||
|
||||
public async Task StaExecuteAsync(Action action)
|
||||
{
|
||||
if (StaDispatcher != null)
|
||||
await StaDispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () => action());
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
private void CloseApplication(TimeSpan delta)
|
||||
{
|
||||
var dispatcherTimer = new DispatcherTimer();
|
||||
dispatcherTimer.Tick += (o, e) => App.Current.Exit();
|
||||
dispatcherTimer.Tick += (o, e) => ShellService.CloseApplication();
|
||||
dispatcherTimer.Interval = delta;
|
||||
dispatcherTimer.Start();
|
||||
}
|
||||
@@ -40,48 +39,21 @@ namespace BlueControl.uwp.ViewModels
|
||||
}
|
||||
|
||||
|
||||
private void Custom_PairingRequested(DeviceInformationCustomPairing sender, DevicePairingRequestedEventArgs args)
|
||||
{
|
||||
|
||||
StaExecuteAsync(() => this.Text = "Pin: " + Environment.NewLine + args.Pin);
|
||||
|
||||
args.Accept(args.Pin);
|
||||
}
|
||||
private readonly Services.IShellService ShellService = Windows.ApplicationModel.DesignMode.DesignModeEnabled
|
||||
? null : Ioc.Default.GetRequiredService<Services.IShellService>();
|
||||
|
||||
private readonly Services.IBluetoothService BluetoothService = Windows.ApplicationModel.DesignMode.DesignModeEnabled
|
||||
? null : Ioc.Default.GetRequiredService<Services.IBluetoothService>();
|
||||
|
||||
|
||||
|
||||
public MainPageViewModel()
|
||||
{
|
||||
this.bleWatcher.Received += async (sender, args) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!args.IsConnectable || control == true) return;
|
||||
control = true;
|
||||
var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
|
||||
if (dev.Name == SURFACE_KEYBOARD_NAME && dev.DeviceInformation.Pairing.CanPair)
|
||||
{
|
||||
await StaExecuteAsync(() => this.Text = "trying to pair... ");
|
||||
this.ReloadCommand = new RelayCommand(async () => await ReloadAsync());
|
||||
|
||||
System.Threading.Thread.Sleep(3000);
|
||||
dev.DeviceInformation.Pairing.Custom.PairingRequested += Custom_PairingRequested;
|
||||
var t = await dev.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.DisplayPin, DevicePairingProtectionLevel.Encryption);
|
||||
if (t.Status == DevicePairingResultStatus.Paired)
|
||||
{
|
||||
this.bleWatcher.Stop();
|
||||
await StaExecuteAsync(() =>
|
||||
{
|
||||
this.Text = $"Paired and connected {Environment.NewLine} auto closing in 2 seconds ";
|
||||
CloseApplication();
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
await StaExecuteAsync(() => this.Text = t.Status.ToString());
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
control = false;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -110,22 +82,32 @@ namespace BlueControl.uwp.ViewModels
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
public ICommand ReloadCommand { get; private set; }
|
||||
|
||||
|
||||
public async Task ReloadAsync()
|
||||
{
|
||||
this.Text = "Loading...";
|
||||
|
||||
IsConnected =
|
||||
(from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromConnectionStatus(BluetoothConnectionStatus.Connected)) where x.Name == SURFACE_KEYBOARD_NAME select x).Any();
|
||||
IsConnected = await BluetoothService.IsConnectedAsync(SURFACE_KEYBOARD_NAME);
|
||||
|
||||
if (!IsConnected)
|
||||
{
|
||||
var pairedDevice =
|
||||
(from x in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelectorFromPairingState(true)) where x.Name == SURFACE_KEYBOARD_NAME select x).FirstOrDefault();
|
||||
if (pairedDevice != null)
|
||||
await pairedDevice.Pairing.UnpairAsync();
|
||||
if (await BluetoothService.IsPairedAsync(SURFACE_KEYBOARD_NAME))
|
||||
await BluetoothService.UnpairAsync(SURFACE_KEYBOARD_NAME);
|
||||
this.Text = $"....searching keyboard. {Environment.NewLine} Please confirm is in pairing mode";
|
||||
this.bleWatcher.Start();
|
||||
await this.BluetoothService.StartAutoPairingAsync(
|
||||
SURFACE_KEYBOARD_NAME,
|
||||
() => this.ShellService.UiStaRunAsync(() => this.Text = "trying to pair... ")
|
||||
, (pin) => this.ShellService.UiStaRunAsync(() => this.Text = $"pin:{Environment.NewLine + pin}")
|
||||
, () =>
|
||||
ShellService.UiStaRunAsync(() =>
|
||||
{
|
||||
this.Text = $"Paired and connected {Environment.NewLine} auto closing in 2 seconds ";
|
||||
CloseApplication();
|
||||
})
|
||||
, () => ShellService.UiStaRunAsync(() => this.Text = "error trying again")
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user