Merge pull request #77 from paulmon/wifi-changes-review

update wifi support to include pushbutton and eap
This commit is contained in:
Paul Monson 2018-01-31 15:58:19 -08:00 коммит произвёл GitHub
Родитель a610ebf778 f812587076
Коммит 55fdf3d302
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 929 добавлений и 415 удалений

Просмотреть файл

@ -3,6 +3,7 @@
using IoTCoreDefaultApp.Utils;
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel;
using Windows.ApplicationModel.Activation;
using Windows.Devices.Enumeration;
@ -40,6 +41,7 @@ namespace IoTCoreDefaultApp
// Don't try and make discoverable if this has already been done
private static bool isDiscoverable = false;
public static NetworkPresenter NetworkPresenter { get; } = new NetworkPresenter();
public static bool IsBluetoothDiscoverable
{
@ -71,7 +73,7 @@ namespace IoTCoreDefaultApp
/// 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)
protected override async void OnLaunched(LaunchActivatedEventArgs e)
{
/*#if DEBUG
@ -130,6 +132,11 @@ namespace IoTCoreDefaultApp
Window.Current.Activate();
Screensaver.InitializeScreensaver();
await Task.Run(async () =>
{
await App.NetworkPresenter.UpdateAvailableNetworksAsync(false);
});
}
protected override void OnActivated(IActivatedEventArgs args)

Просмотреть файл

@ -125,6 +125,7 @@
<Compile Include="Presenters\DeviceInfoPresenter.cs" />
<Compile Include="Presenters\LanguageManager.cs" />
<Compile Include="Presenters\NetworkPresenter.cs" />
<Compile Include="Presenters\WifiListViewItemPresenter.cs" />
<Compile Include="UserControls\NetworkListControl.xaml.cs">
<DependentUpon>NetworkListControl.xaml</DependentUpon>
</Compile>

Просмотреть файл

@ -1,9 +1,12 @@
// Copyright (c) Microsoft. All rights reserved.
using IoTCoreDefaultApp.Presenters;
using IoTCoreDefaultApp.Utils;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@ -13,6 +16,7 @@ using Windows.Devices.WiFi;
using Windows.Networking;
using Windows.Networking.Connectivity;
using Windows.Security.Credentials;
using Windows.System.Threading;
namespace IoTCoreDefaultApp
{
@ -24,32 +28,48 @@ namespace IoTCoreDefaultApp
private DeviceWatcher WiFiAdaptersWatcher;
ManualResetEvent EnumAdaptersCompleted = new ManualResetEvent(false);
private ConcurrentDictionary<WiFiAvailableNetwork, WiFiAdapter> NetworkNameToInfo = new ConcurrentDictionary<WiFiAvailableNetwork, WiFiAdapter>();
private SemaphoreSlim NetworkNameToInfoLock = new SemaphoreSlim(1, 1);
private ConcurrentDictionary<string, WifiListViewItemPresenter> AvailableNetworks = new ConcurrentDictionary<string, WifiListViewItemPresenter>();
private SemaphoreSlim AvailableNetworksLock = new SemaphoreSlim(1, 1);
private static WiFiAccessStatus? accessStatus;
private ThreadPoolTimer wifiRefreshTimer;
private TimeSpan refreshTimespan = TimeSpan.FromMinutes(5);
private TimeSpan expiredTimespan = TimeSpan.FromMinutes(7);
public NetworkPresenter()
{
WiFiAdaptersWatcher = DeviceInformation.CreateWatcher(WiFiAdapter.GetDeviceSelector());
WiFiAdaptersWatcher.EnumerationCompleted += AdaptersEnumCompleted;
WiFiAdaptersWatcher.Added += AdaptersAdded;
WiFiAdaptersWatcher.Removed += AdaptersRemoved;
WiFiAdaptersWatcher.Start();
Log.Enter();
Task.Run(() =>
{
if (TestAccess().Result)
{
WiFiAdaptersWatcher = DeviceInformation.CreateWatcher(WiFiAdapter.GetDeviceSelector());
WiFiAdaptersWatcher.EnumerationCompleted += AdaptersEnumCompleted;
WiFiAdaptersWatcher.Added += AdaptersAdded;
WiFiAdaptersWatcher.Removed += AdaptersRemoved;
WiFiAdaptersWatcher.Start();
}
});
Log.Leave();
}
private void AdaptersRemoved(DeviceWatcher sender, DeviceInformationUpdate args)
{
Log.Enter();
WiFiAdapters.Remove(args.Id);
Log.Leave();
}
private void AdaptersAdded(DeviceWatcher sender, DeviceInformation args)
{
Log.Enter();
WiFiAdapters.Add(args.Id, null);
Log.Leave();
}
private async void AdaptersEnumCompleted(DeviceWatcher sender, object args)
{
Log.Enter();
List<String> WiFiAdaptersID = new List<string>(WiFiAdapters.Keys);
for(int i = 0; i < WiFiAdaptersID.Count; i++)
{
@ -64,10 +84,23 @@ namespace IoTCoreDefaultApp
}
}
EnumAdaptersCompleted.Set();
if (WiFiAdapters.Count() > 0)
{
wifiRefreshTimer = ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick, refreshTimespan);
}
Log.Leave();
}
private void Timer_Tick(ThreadPoolTimer timer)
{
Log.Enter();
App.NetworkPresenter.UpdateAvailableNetworksAsync(false).Wait();
Log.Leave();
}
public static string GetDirectConnectionName()
{
Log.Enter();
try
{
var icp = NetworkInformation.GetInternetConnectionProfile();
@ -82,11 +115,13 @@ namespace IoTCoreDefaultApp
// seeing cases where NetworkInformation.GetInternetConnectionProfile() fails
}
Log.Leave();
return null;
}
public static string GetCurrentNetworkName()
{
Log.Enter();
try
{
var icp = NetworkInformation.GetInternetConnectionProfile();
@ -103,11 +138,13 @@ namespace IoTCoreDefaultApp
var resourceLoader = ResourceLoader.GetForCurrentView();
var msg = resourceLoader.GetString("NoInternetConnection");
Log.Leave();
return msg;
}
public static string GetCurrentIpv4Address()
{
Log.Enter();
try
{
var icp = NetworkInformation.GetInternetConnectionProfile();
@ -138,12 +175,14 @@ namespace IoTCoreDefaultApp
var resourceLoader = ResourceLoader.GetForCurrentView();
var msg = resourceLoader.GetString("NoInternetConnection");
Log.Leave();
return msg;
}
// Call this method before accessing WiFiAdapters Dictionary
private async Task UpdateAdapters()
{
Log.Enter();
bool fInit = false;
foreach (var adapter in WiFiAdapters)
{
@ -170,9 +209,12 @@ namespace IoTCoreDefaultApp
}
}
}
Log.Leave();
}
public async Task<bool> WifiIsAvailable()
{
Log.Enter();
if ((await TestAccess()) == false)
{
return false;
@ -181,7 +223,11 @@ namespace IoTCoreDefaultApp
try
{
EnumAdaptersCompleted.WaitOne();
await UpdateAdapters();
if (WiFiAdapters.Count == 0)
{
await UpdateAdapters();
}
Log.Leave();
return (WiFiAdapters.Count > 0);
}
catch (Exception)
@ -190,18 +236,39 @@ namespace IoTCoreDefaultApp
}
}
private async Task<bool> UpdateInfo()
private DateTime LastRefresh = DateTime.MinValue;
public bool IsRefreshNeeded()
{
Log.Enter();
bool result = false;
if (DateTime.Now > (LastRefresh + expiredTimespan))
{
result = true;
}
Log.Leave($"result={result}");
return result;
}
public async Task<bool> UpdateAvailableNetworksAsync(bool refreshIfNeeded)
{
Log.Enter($"refreshIfNeeded={refreshIfNeeded}");
try
{
await NetworkNameToInfoLock.WaitAsync();
await AvailableNetworksLock.WaitAsync();
if ((await TestAccess()) == false)
{
return false;
}
NetworkNameToInfo.Clear();
if (refreshIfNeeded && !IsRefreshNeeded())
{
return true;
}
LastRefresh = DateTime.Now;
EnumAdaptersCompleted.WaitOne();
List<WiFiAdapter> WiFiAdaptersList = new List<WiFiAdapter>(WiFiAdapters.Values);
foreach (var adapter in WiFiAdaptersList)
{
@ -225,52 +292,69 @@ namespace IoTCoreDefaultApp
continue;
}
DateTime reportTime = DateTime.Now;
foreach (var network in adapter.NetworkReport.AvailableNetworks)
{
if (!HasSsid(NetworkNameToInfo, network.Ssid))
if (!String.IsNullOrWhiteSpace(network.Ssid))
{
NetworkNameToInfo[network] = adapter;
if (AvailableNetworks.ContainsKey(network.Ssid))
{
WifiListViewItemPresenter value;
AvailableNetworks.TryRemove(network.Ssid, out value);
}
var item = new WifiListViewItemPresenter(network, adapter, reportTime);
if (AvailableNetworks.TryAdd(network.Ssid, item))
{
await item.InitializeAsync();
Log.Trace($"Adding {network.Ssid}");
}
}
}
// remove some jitter from the list when refresh is repeatedly clicked
// by remembering networks from the last 5 minutes
DateTime expireTime = DateTime.Now - TimeSpan.FromMinutes(5);
foreach(var key in AvailableNetworks.Keys)
{
if (AvailableNetworks[key].LastSeen < expireTime)
{
WifiListViewItemPresenter value;
AvailableNetworks.TryRemove(key, out value);
}
}
}
Log.Leave();
return true;
}
finally
{
NetworkNameToInfoLock.Release();
AvailableNetworksLock.Release();
}
}
private bool HasSsid(ConcurrentDictionary<WiFiAvailableNetwork, WiFiAdapter> resultCollection, string ssid)
public async Task<IList<WifiListViewItemPresenter>> GetAvailableNetworks(bool refreshIfNeeded)
{
foreach (var network in resultCollection)
{
if (!string.IsNullOrEmpty(network.Key.Ssid) && network.Key.Ssid == ssid)
{
return true;
}
}
return false;
}
public async Task<IList<WiFiAvailableNetwork>> GetAvailableNetworks()
{
await UpdateInfo();
Log.Enter();
await UpdateAvailableNetworksAsync(refreshIfNeeded);
try
{
await NetworkNameToInfoLock.WaitAsync();
return NetworkNameToInfo.Keys.ToList();
await AvailableNetworksLock.WaitAsync();
var availableNetworks = AvailableNetworks.Values.ToList();
availableNetworks.Sort((item1, item2) => item2.AvailableNetwork.SignalBars.CompareTo(item1.AvailableNetwork.SignalBars));
return availableNetworks;
}
finally
{
NetworkNameToInfoLock.Release();
AvailableNetworksLock.Release();
}
}
public WiFiAvailableNetwork GetCurrentWifiNetwork()
static public string GetConnectedProfileName()
{
Log.Enter();
IReadOnlyCollection<ConnectionProfile> connectionProfiles = null;
try
{
@ -299,124 +383,108 @@ namespace IoTCoreDefaultApp
var firstProfile = validProfiles.First() as ConnectionProfile;
try
{
NetworkNameToInfoLock.WaitAsync().ConfigureAwait(false);
return NetworkNameToInfo.Keys.FirstOrDefault(wifiNetwork => wifiNetwork.Ssid.Equals(firstProfile.ProfileName));
}
finally
{
NetworkNameToInfoLock.Release();
}
Log.Leave();
return firstProfile.ProfileName;
}
public async Task<bool> ConnectToNetwork(WiFiAvailableNetwork network, bool autoConnect)
public WifiListViewItemPresenter GetCurrentWifiNetwork()
{
Log.Enter();
try
{
await NetworkNameToInfoLock.WaitAsync();
if (network == null)
AvailableNetworksLock.WaitAsync().ConfigureAwait(false);
string connectedProfile = GetConnectedProfileName();
if (connectedProfile != null)
{
return false;
WifiListViewItemPresenter network;
AvailableNetworks.TryGetValue(connectedProfile, out network);
Log.Leave();
return network;
}
// We need to use TryGetValue here. If we are rescanning for Wifi networks
// (ie. 'await'ing on ScanAsync() in UpdateInfo(), 'NetworkNameToInfo' may not
// have an entry described by the key'network'.
WiFiAdapter wifiAdapter;
if (!NetworkNameToInfo.TryGetValue(network, out wifiAdapter))
else
{
return false;
}
try
{
var result = await wifiAdapter.ConnectAsync(network, autoConnect ? WiFiReconnectionKind.Automatic : WiFiReconnectionKind.Manual);
//Call redirect only for Open Wifi
if (IsNetworkOpen(network))
{
//Navigate to http://www.msftconnecttest.com/redirect
NavigationUtils.NavigateToScreen(typeof(WebBrowserPage), Common.GetResourceText("MicrosoftWifiConnect"));
}
return (result.ConnectionStatus == WiFiConnectionStatus.Success);
}
catch (Exception)
{
return false;
return null;
}
}
finally
{
NetworkNameToInfoLock.Release();
AvailableNetworksLock.Release();
}
}
public void DisconnectNetwork(WiFiAvailableNetwork network)
public async Task<WiFiConnectionStatus> ConnectToNetwork(WifiListViewItemPresenter network, bool autoConnect)
{
Log.Enter();
await AvailableNetworksLock.WaitAsync();
if (network == null)
{
return WiFiConnectionStatus.UnspecifiedFailure;
}
try
{
NetworkNameToInfoLock.Wait();
NetworkNameToInfo[network].Disconnect();
var result = await network.Adapter.ConnectAsync(network.AvailableNetwork, autoConnect ? WiFiReconnectionKind.Automatic : WiFiReconnectionKind.Manual);
//Call redirect only for Open Wifi
if (IsNetworkOpen(network))
{
//Navigate to http://www.msftconnecttest.com/redirect
NavigationUtils.NavigateToScreen(typeof(WebBrowserPage), Common.GetResourceText("MicrosoftWifiConnect"));
}
Log.Leave($"LEAVE {result.ConnectionStatus}");
return result.ConnectionStatus;
}
finally
catch (Exception)
{
NetworkNameToInfoLock.Release();
return WiFiConnectionStatus.UnspecifiedFailure;
}
}
public static bool IsNetworkOpen(WiFiAvailableNetwork network)
public void DisconnectNetwork(WifiListViewItemPresenter network)
{
return network.SecuritySettings.NetworkEncryptionType == NetworkEncryptionType.None;
Log.Enter();
network.Adapter.Disconnect();
Log.Leave();
}
public async Task<bool> ConnectToNetworkWithPassword(WiFiAvailableNetwork network, bool autoConnect, PasswordCredential password)
public static bool IsNetworkOpen(WifiListViewItemPresenter network)
{
Log.Enter();
return network.AvailableNetwork.SecuritySettings.NetworkEncryptionType == NetworkEncryptionType.None;
}
public async Task<WiFiConnectionStatus> ConnectToNetworkWithPassword(WifiListViewItemPresenter network, bool autoConnect, PasswordCredential password)
{
Log.Enter();
try
{
await NetworkNameToInfoLock.WaitAsync();
if (network == null)
{
return false;
}
var result = await network.Adapter.ConnectAsync(
network.AvailableNetwork,
autoConnect ? WiFiReconnectionKind.Automatic : WiFiReconnectionKind.Manual,
password);
// We need to use TryGetValue here. If we are rescanning for Wifi networks
// (ie. 'await'ing on ScanAsync() in UpdateInfo(), 'NetworkNameToInfo' may not
// have an entry described by the key'network'.
WiFiAdapter wifiAdapter;
if (!NetworkNameToInfo.TryGetValue(network, out wifiAdapter))
{
return false;
}
try
{
var result = await wifiAdapter.ConnectAsync(
network,
autoConnect ? WiFiReconnectionKind.Automatic : WiFiReconnectionKind.Manual,
password);
return (result.ConnectionStatus == WiFiConnectionStatus.Success);
}
catch (Exception)
{
return false;
}
Log.Leave($"LEAVE {result.ConnectionStatus}");
return result.ConnectionStatus;
}
finally
catch (Exception)
{
NetworkNameToInfoLock.Release();
return WiFiConnectionStatus.UnspecifiedFailure;
}
}
private static async Task<bool> TestAccess()
{
Log.Enter();
if (!accessStatus.HasValue)
{
accessStatus = await WiFiAdapter.RequestAccessAsync();
}
Log.Leave();
return (accessStatus == WiFiAccessStatus.Allowed);
}
@ -431,6 +499,7 @@ namespace IoTCoreDefaultApp
public static async Task<IList<NetworkInfo>> GetNetworkInformation()
{
Log.Enter();
var networkList = new Dictionary<Guid, NetworkInfo>();
try
@ -504,6 +573,7 @@ namespace IoTCoreDefaultApp
var res = new List<NetworkInfo>();
res.AddRange(networkList.Values);
Log.Leave();
return res;
}
}

Просмотреть файл

@ -0,0 +1,241 @@
using IoTCoreDefaultApp.Utils;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using Windows.Devices.WiFi;
using Windows.Foundation.Metadata;
using Windows.Networking.Connectivity;
using Windows.UI.Xaml;
namespace IoTCoreDefaultApp.Presenters
{
public class WifiListViewItemPresenter : INotifyPropertyChanged
{
private TimeSpan expiredTimespan = TimeSpan.FromMinutes(5);
public WifiListViewItemPresenter(WiFiAvailableNetwork availableNetwork, WiFiAdapter adapter, DateTime reportTime)
{
AvailableNetwork = availableNetwork;
this.adapter = adapter;
this.LastSeen = reportTime;
}
public async Task InitializeAsync()
{
if (!IsWpsPushButtonAvailable.HasValue)
{
IsWpsPushButtonAvailable = await Task<bool>.Run(async () =>
{
return await IsWpsPushButtonAvailableAsync();
});
}
}
private WiFiAdapter adapter;
public WiFiAdapter Adapter
{
get
{
return adapter;
}
}
public void Disconnect()
{
adapter.Disconnect();
}
public bool? IsWpsPushButtonAvailable { get; set; }
public bool NetworkKeyInfoVisibility
{
get
{
if ((AvailableNetwork.SecuritySettings.NetworkAuthenticationType == NetworkAuthenticationType.Open80211 &&
AvailableNetwork.SecuritySettings.NetworkEncryptionType == NetworkEncryptionType.None) ||
IsEapAvailable)
{
return false;
}
return true;
}
}
private bool usePassword = false;
public bool UsePassword
{
get
{
return usePassword;
}
set
{
usePassword = value;
OnPropertyChanged("UsePassword");
}
}
private bool connectAutomatically = true;
public bool ConnectAutomatically
{
get
{
return connectAutomatically;
}
set
{
connectAutomatically = value;
OnPropertyChanged("ConnectAutomatically");
}
}
public String Ssid
{
get
{
return availableNetwork.Ssid;
}
}
public byte SignalBars
{
get
{
return AvailableNetwork.SignalBars;
}
}
private string userName;
public string UserName
{
get { return userName; }
set { userName = value; OnPropertyChanged("UserName"); }
}
private string password;
public string Password
{
get { return password; }
set { password = value; OnPropertyChanged("Password"); }
}
private string domain;
public string Domain
{
get { return domain; }
set { domain = value; OnPropertyChanged("Domain"); }
}
public bool IsEapAvailable
{
get
{
Log.Trace($"{availableNetwork.SecuritySettings.NetworkAuthenticationType}");
return ((availableNetwork.SecuritySettings.NetworkAuthenticationType == NetworkAuthenticationType.Rsna) ||
(availableNetwork.SecuritySettings.NetworkAuthenticationType == NetworkAuthenticationType.Wpa));
}
}
public async Task<bool> IsWpsPushButtonAvailableAsync()
{
return await Task.Run(async () =>
{
await Task.CompletedTask;
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 5, 0))
{
var task = adapter.GetWpsConfigurationAsync(availableNetwork).AsTask();
bool success = task.Wait(1000);
if (success)
{
if (task.Result.SupportedWpsKinds.Contains(WiFiWpsKind.PushButton))
{
return true;
}
else
{
return false;
}
}
else
{
// GetWpsConfigurationAsync is not returning sometimes
// If the result isn't available let the user figure out if WPS is supported or not
Log.Trace($"GetWpsConfigurationAsync timed out: {availableNetwork.Ssid}");
return true;
}
}
return false;
});
}
private WiFiAvailableNetwork availableNetwork;
public WiFiAvailableNetwork AvailableNetwork
{
get
{
return availableNetwork;
}
private set
{
availableNetwork = value;
}
}
private string message;
public string Message
{
get
{
return message;
}
set
{
message = value;
OnPropertyChanged("Message");
}
}
private bool isMessageVisible = false;
public bool IsMessageVisible
{
get
{
return isMessageVisible;
}
set
{
isMessageVisible = value;
OnPropertyChanged("IsMessageVisible");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
public DateTime LastSeen { get; set; }
public bool IsExpired
{
get
{
if (LastSeen + expiredTimespan < DateTime.Now)
{
return true;
}
return false;
}
}
}
}

Просмотреть файл

@ -766,6 +766,36 @@ Alternatively, click or tap the button below to enter your Administrator account
<data name="PasswordText" xml:space="preserve">
<value>Password</value>
</data>
<data name="DomainText" xml:space="preserve">
<value>Domain</value>
</data>
<data name="WpsText" xml:space="preserve">
<value>WPS</value>
</data>
<data name="UnspecifiedFailureText" xml:space="preserve">
<value>Unspecified Failure</value>
</data>
<data name="SuccessText" xml:space="preserve">
<value>Success</value>
</data>
<data name="AccessRevokedText" xml:space="preserve">
<value>Access Revoked</value>
</data>
<data name="InvalidCredentialText" xml:space="preserve">
<value>Invalid Credential</value>
</data>
<data name="NetworkNotAvailableText" xml:space="preserve">
<value>Network Not Available</value>
</data>
<data name="TimeoutText" xml:space="preserve">
<value>Connection Timed Out</value>
</data>
<data name="UnsupportedAuthenticationProtocolText" xml:space="preserve">
<value>Unsupported Authentication Protocol</value>
</data>
<data name="UsePasswordText" xml:space="preserve">
<value>Use password</value>
</data>
<data name="CmdTextEnabledSuccess" xml:space="preserve">
<value>Successfully enabled Command Line Processor (cmd.exe) on your device.</value>
</data>

Просмотреть файл

@ -59,6 +59,7 @@
<SolidColorBrush x:Key="PaleTextBrush" Color="White" Opacity="0.6"/>
<SolidColorBrush x:Key="DarkAccentBrush" Color="{StaticResource DarkAccentColor}"/>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource AccentColor}"/>
<SolidColorBrush x:Key="AccentBorderBrush" Color="{StaticResource AccentBorderColor}" />
<SolidColorBrush x:Key="HoverBrush" Color="{StaticResource AccentColor}" Opacity="0.2"/>
<!--<SolidColorBrush x:Key="ListViewItemSelectedPointerOverBorderThemeBrush" Color="Transparent" />
@ -218,6 +219,16 @@
</Setter>
</Style>
<Style x:Key="SignalBarsStyle" TargetType="TextBlock">
<Setter Property="Width" Value="40" />
<Setter Property="Height" Value="40" />
<Setter Property="FontSize" Value="40" />
<Setter Property="Margin" Value="5" />
<Setter Property="FontFamily" Value="{StaticResource IconFontFamily}" />
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="HorizontalAlignment" Value="Center" />
</Style>
<Style x:Key="LanguageSelectionListViewItemStyle" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
@ -286,9 +297,9 @@
<Setter Property="Background" Value="Transparent"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Margin" Value="0,0,0,4"/>
<Setter Property="Padding" Value="12,0,14,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="Margin" Value="4,4,4,4"/>
<Setter Property="Padding" Value="12,6,14,6"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>

Просмотреть файл

@ -1,162 +1,156 @@
<UserControl
x:Class="IoTCoreDefaultApp.NetworkListControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:IoTCoreDefaultApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400"
x:Name="rootControl">
<UserControl x:Class="IoTCoreDefaultApp.NetworkListControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:IoTCoreDefaultApp" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" x:Name="rootControl">
<UserControl.Resources>
<local:WifiGlyphConverter x:Key="GlyphConverter"/>
<DataTemplate x:Name="WifiInitialState">
<Grid Height="44">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource AccentBrush}" Grid.Row="0" Grid.Column="0" Width="32" Height="32" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Grid.Column="0" Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" FontSize="18" FontFamily="{StaticResource IconFontFamily}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<TextBlock Grid.Column="1" Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" Margin="5,0,0,0"/>
</Grid>
</DataTemplate>
<DataTemplate x:Name="WifiConnectedState">
<Grid Height="44">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="{StaticResource AccentBrush}" Grid.Row="0" Grid.Column="0" Width="32" Height="32" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Grid.Column="0" Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" FontSize="18" FontFamily="{StaticResource IconFontFamily}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<StackPanel Grid.Column="1" Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="5,0,0,0">
<TextBlock Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}"/>
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[NetworkConnectedText]}" Style="{StaticResource BodyTextBlockStyle}" Foreground="{StaticResource PaleTextBrush}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Name="WifiConnectState">
<Grid Height="144">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="44"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="26"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Border Width="32" Height="32" VerticalAlignment="Center">
<TextBlock Grid.Column="0" Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" FontSize="18" FontFamily="{StaticResource IconFontFamily}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<TextBlock Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" Margin="5,0,0,0"/>
</StackPanel>
<CheckBox Grid.Row="1" x:Name="ConnectAutomaticallyCheckBox" IsChecked="True" HorizontalAlignment="Left" Margin="45,0,0,0" Height="32" Checked="ConnectAutomaticallyCheckBox_Changed" Unchecked="ConnectAutomaticallyCheckBox_Changed" Style="{StaticResource IoTCoreDefaultAppCheckBoxStyle}">
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[ConnectAutomaticallyText]}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}"/>
</CheckBox>
<Button Grid.Row="3" Content="{Binding ElementName='rootControl', Path=DataContext[ConnectButtonContent]}" x:Name="ConnectButton" Width="120" Height="32" HorizontalAlignment="Left" VerticalAlignment="Bottom" Click="ConnectButton_Clicked" Margin="102,0,0,0"/>
</Grid>
</DataTemplate>
<DataTemplate x:Name="WifiConnectedMoreOptions">
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="44"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<Border Width="32" Height="32" VerticalAlignment="Center">
<TextBlock Grid.Column="0" Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" FontSize="18" FontFamily="{StaticResource IconFontFamily}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<TextBlock Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" Margin="5,0,0,0"/>
</StackPanel>
<Button Grid.Row="1" Content="{Binding ElementName='rootControl', Path=DataContext[DisconnectButtonContent]}" x:Name="DisconnectButton" Width="120" Height="32" HorizontalAlignment="Left" VerticalAlignment="Bottom" Click="DisconnectButton_Clicked" Margin="102,0,0,0"/>
</Grid>
</DataTemplate>
<DataTemplate x:Name="WifiPasswordState">
<Grid Height="204">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="44"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="50"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="8"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Grid.Column="0" Width="32" Height="32" VerticalAlignment="Center">
<TextBlock Grid.Column="0" Grid.Row="0" Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" FontSize="18" FontFamily="{StaticResource IconFontFamily}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" Margin="5,0,0,0"/>
<StackPanel Orientation="Vertical" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Stretch">
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[NetworkPasswordPromptText]}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}"/>
<PasswordBox x:Name="WifiPasswordBox" PasswordChanged="WifiPasswordBox_PasswordChanged" HorizontalAlignment="Stretch" VerticalAlignment="Center" Width="334" Margin="0,8,0,0" Loaded="WifiPasswordBox_Loaded"/>
</StackPanel>
<StackPanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="130,0,0,0">
<Button Content="{Binding ElementName='rootControl', Path=DataContext[NextButtonContent]}" x:Name="NextButton" Width="120" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="NextButton_Clicked" Height="32"/>
<Button Content="{Binding ElementName='rootControl', Path=DataContext[CancelButtonContent]}" x:Name="CancelButton" Width="120" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="CancelButton_Clicked" Margin="12,0,0,0" Height="32"/>
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Name="WifiConnectingState">
<Grid Height="138">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="44"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="26"/>
<RowDefinition Height="*"/>
<RowDefinition Height="8"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" Grid.Column="0" Width="32" Height="32" VerticalAlignment="Center">
<TextBlock Grid.Column="0" Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" FontSize="18" FontFamily="{StaticResource IconFontFamily}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" Margin="5,0,0,0"/>
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="1">
<ProgressRing x:Name="ConnectingProgressRing" IsActive="True" Foreground="White"/>
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[NetworkConnectingMessageText]}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" Margin="12,0,0,0"/>
</StackPanel>
<Button Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="2" x:Name="CancelButton" Content="Cancel" Width="120" HorizontalAlignment="Left" VerticalAlignment="Bottom" Click="CancelButton_Clicked" Margin="130,0,0,0"/>
</Grid>
</DataTemplate>
</UserControl.Resources>
<StackPanel x:Name="NetworkGrid" Margin="24,25,0,0" Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Top">
<TextBlock Text="{Binding [DirectConnectionsText]}" Style="{StaticResource SubtitleTextBlockStyle}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,12"/>
<TextBlock Text="{Binding [NoNetworksText]}" x:Name="NoneFoundText" Style="{StaticResource SubtitleTextBlockStyle}" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Collapsed"/>
<StackPanel x:Name="DirectConnectionStackPanel" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Top">
<Border Width="44" Height="44">
<TextBlock Text="{StaticResource ResourceKey=IconEthernet}" FontSize="24" FontFamily="{StaticResource IconFontFamily}" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Border>
<TextBlock Text="{Binding [EthernetText]}" Style="{StaticResource BodyTextBlockStyle}" VerticalAlignment="Center"/>
<UserControl.Resources>
<local:WifiGlyphConverter x:Key="GlyphConverter" />
<DataTemplate x:Name="WifiInitialState">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" Style="{StaticResource SignalBarsStyle}" />
<TextBlock Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="WifiConnectedState">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" Style="{StaticResource SignalBarsStyle}" />
<StackPanel Grid.Column="1" Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="15,0,0,0">
<TextBlock Text="{Binding Ssid}" Style="{StaticResource BodyTextBlockStyle}" />
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[NetworkConnectedText]}" Style="{StaticResource BodyTextBlockStyle}" Foreground="{StaticResource PaleTextBrush}" />
</StackPanel>
<Grid Margin="0,21,0,0">
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="WifiConnectState">
<StackPanel Orientation="Vertical" Margin="0,0,0,6">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" Style="{StaticResource SignalBarsStyle}" />
<TextBlock Text="{Binding Ssid}" Style="{StaticResource BodyTextBlockStyle}" VerticalAlignment="Center" />
</StackPanel>
<StackPanel Orientation="Vertical" Margin="0,5,0,0">
<TextBlock Text="{Binding Message}" Style="{StaticResource BodyTextBlockStyle}" Visibility="{Binding IsMessageVisible}" Margin="0,15,0,15" />
<CheckBox IsChecked="{Binding Path=ConnectAutomatically, Mode=TwoWay}" Style="{StaticResource IoTCoreDefaultAppCheckBoxStyle}">
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[ConnectAutomaticallyText]}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" />
</CheckBox>
<Button Content="{Binding ElementName='rootControl', Path=DataContext[ConnectButtonContent]}" x:Name="ConnectButton" Width="120" Height="32" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="ConnectButton_Click" />
</StackPanel>
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="WifiConnectedMoreOptions">
<StackPanel HorizontalAlignment="Stretch" Orientation="Vertical">
<StackPanel Orientation="Horizontal" Margin="0,0,0,14">
<TextBlock Grid.Column="0" Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" Style="{StaticResource SignalBarsStyle}" />
<StackPanel Grid.Column="1" Orientation="Vertical" HorizontalAlignment="Left" VerticalAlignment="Center">
<TextBlock Text="{Binding Ssid}" Style="{StaticResource BodyTextBlockStyle}" />
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[NetworkConnectedText]}" Style="{StaticResource BodyTextBlockStyle}" Foreground="{StaticResource PaleTextBrush}" />
</StackPanel>
</StackPanel>
<Button Content="{Binding ElementName='rootControl', Path=DataContext[DisconnectButtonContent]}" Width="120" Height="32" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="DisconnectButton_Clicked" Margin="0,0,0,6" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Name="WifiPasswordState">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" Style="{StaticResource SignalBarsStyle}" />
<TextBlock Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" />
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Vertical" HorizontalAlignment="Stretch" Visibility="{Binding Path=NetworkKeyInfoVisibility}" Margin="0,12,0,0">
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[NetworkPasswordPromptText]}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" />
<PasswordBox Password="{Binding Path=Password, Mode=TwoWay}" HorizontalAlignment="Stretch" Width="334" Margin="0,8,0,0" Loaded="WifiPasswordBox_Loaded" />
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,12,0,6">
<Button x:Name="PushButtonConnectButton" Visibility="{Binding Path=IsWpsPushButtonAvailable}" Width="120" Height="32" Margin="12,0,0,0" Click="PushButtonConnect_Click">
<StackPanel Orientation="Horizontal">
<FontIcon FontFamily="Segoe MDL2 Assets" Glyph="&#xE895;" FontSize="20"/>
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[WpsText]}" Margin="12,0,0,0" />
</StackPanel>
</Button>
<Button Content="{Binding ElementName='rootControl', Path=DataContext[NextButtonContent]}" x:Name="NextButton" Width="120" Height="32" Click="NextButton_Clicked" Margin="12,0,0,0" />
<Button Content="{Binding ElementName='rootControl', Path=DataContext[CancelButtonContent]}" x:Name="CancelButton" Width="120" Height="32" Click="CancelButton_Clicked" Margin="12,0,0,0" />
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Name="WifiEapPasswordState">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal" Margin="0,6,0,0">
<TextBlock Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" Style="{StaticResource SignalBarsStyle}" />
<TextBlock Text="{Binding Ssid}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" />
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Vertical" Visibility="{Binding Path=IsEapAvailable}" Margin="0,12,0,0">
<CheckBox IsChecked="{Binding Path=UsePassword, Mode=TwoWay}" Visibility="{Binding Path=IsEapAvailable}">
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[UsePasswordText]}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" />
</CheckBox>
<Grid x:Name="EapInfo" Visibility="{Binding Path=UsePassword}" Margin="0,12,0,0">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding [WifiText]}" Style="{StaticResource SubtitleTextBlockStyle}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,12,0,12"/>
<Button Grid.Column="2" x:Name="RefreshButton" Content="{Binding [RefreshContent]}" Click="RefreshButton_Click" />
</Grid>
<ListView x:Name="WifiListView" HorizontalAlignment="Left" VerticalAlignment="Top" SelectionMode="Single" Width="446" ItemTemplate="{StaticResource WifiInitialState}" SelectionChanged="WifiListView_SelectionChanged" ItemContainerStyle="{StaticResource WifiListViewItemStyle}" ItemClick="WifiListView_ItemClick" IsItemClickEnabled="True" />
<TextBlock Text="{Binding [NoNetworksText]}" x:Name="NoWifiFoundText" Width="446" Style="{StaticResource BodyTextBlockStyle}" HorizontalAlignment="Left" VerticalAlignment="Top" Visibility="Collapsed" Margin="10,0,0,0"/>
<TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding ElementName='rootControl', Path=DataContext[UsernameText]}" HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" Text="{Binding Path=UserName, Mode=TwoWay}" Margin="24,6,0,0" VerticalAlignment="Center" />
<TextBlock Grid.Row="1" Grid.Column="0" Text="{Binding ElementName='rootControl', Path=DataContext[DomainText]}" HorizontalAlignment="Right" VerticalAlignment="Center" />
<TextBox Grid.Row="1" Grid.Column="1" HorizontalAlignment="Stretch" Text="{Binding Path=Domain, Mode=TwoWay}" Margin="24,6,0,0" VerticalAlignment="Center" />
<TextBlock Grid.Row="2" Grid.Column="0" Text="{Binding ElementName='rootControl', Path=DataContext[PasswordText]}" HorizontalAlignment="Right" VerticalAlignment="Center" />
<PasswordBox Grid.Row="2" Grid.Column="1" HorizontalAlignment="Stretch" Password="{Binding Path=Password, Mode=TwoWay}" Margin="24,6,0,0" VerticalAlignment="Center" />
</Grid>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal" Margin="0,24,0,6" HorizontalAlignment="Right">
<Button Content="{Binding ElementName='rootControl', Path=DataContext[NextButtonContent]}" x:Name="NextButton" Width="120" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="NextButton_Clicked" Margin="12,0,0,0" Height="32" />
<Button Content="{Binding ElementName='rootControl', Path=DataContext[CancelButtonContent]}" x:Name="CancelButton" Width="120" HorizontalAlignment="Right" VerticalAlignment="Bottom" Click="CancelButton_Clicked" Margin="12,0,0,0" Height="32" />
</StackPanel>
</Grid>
</DataTemplate>
<DataTemplate x:Name="WifiConnectingState">
<StackPanel Orientation="Vertical" HorizontalAlignment="Stretch">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding SignalBars, Mode=OneWay, Converter={StaticResource GlyphConverter}}" Style="{StaticResource SignalBarsStyle}" />
<TextBlock Text="{Binding Ssid}" Style="{StaticResource BodyTextBlockStyle}" VerticalAlignment="Center"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Column="1" Grid.Row="1" Margin="0,14,0,14">
<ProgressRing x:Name="ConnectingProgressRing" IsActive="True" Foreground="White" />
<TextBlock Text="{Binding ElementName='rootControl', Path=DataContext[NetworkConnectingMessageText]}" HorizontalAlignment="Left" VerticalAlignment="Center" Style="{StaticResource BodyTextBlockStyle}" Margin="12,0,0,0" />
</StackPanel>
<Button x:Name="CancelButton" Content="{Binding ElementName='rootControl', Path=DataContext[CancelButtonContent]}" Width="120" HorizontalAlignment="Right" Click="CancelButton_Clicked" Margin="130,0,0,0" />
</StackPanel>
</DataTemplate>
</UserControl.Resources>
<Grid x:Name="NetworkGrid" HorizontalAlignment="Left" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding [DirectConnectionsText]}" Style="{StaticResource SubtitleTextBlockStyle}" Margin="0,0,0,12" />
<TextBlock Grid.Row="1" Text="{Binding [NoNetworksText]}" x:Name="NoneFoundText" Style="{StaticResource SubtitleTextBlockStyle}" Visibility="Collapsed" />
<StackPanel Grid.Row="2" x:Name="DirectConnectionStackPanel" Orientation="Horizontal" HorizontalAlignment="Stretch">
<Border Width="44" Height="44">
<TextBlock Text="{StaticResource ResourceKey=IconEthernet}" FontSize="24" FontFamily="{StaticResource IconFontFamily}" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Border>
<TextBlock Text="{Binding [EthernetText]}" Style="{StaticResource BodyTextBlockStyle}" VerticalAlignment="Center" />
</StackPanel>
<Grid Grid.Row="3" Margin="0,21,0,12" MaxWidth="446" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="12" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding [WifiText]}" Style="{StaticResource SubtitleTextBlockStyle}" HorizontalAlignment="Left" />
<Button Grid.Row="0" x:Name="RefreshButton" Content="{Binding [RefreshContent]}" Click="RefreshButton_Click" HorizontalAlignment="Right" />
<ProgressRing Grid.Row="0" x:Name="RefreshProgressRing" IsActive="True" Foreground="White" Visibility="Collapsed" HorizontalAlignment="Right"/>
<ListView Grid.Row="2" x:Name="WifiListView" SelectionMode="Single" Width="446" VerticalAlignment="Stretch" ItemTemplate="{StaticResource WifiInitialState}" SelectionChanged="WifiListView_SelectionChanged" ItemContainerStyle="{StaticResource WifiListViewItemStyle}" ItemClick="WifiListView_ItemClick" IsItemClickEnabled="True" BorderBrush="DimGray" BorderThickness="1" />
<TextBlock Grid.Row="2" Text="{Binding [NoNetworksText]}" x:Name="NoWifiFoundText" MaxWidth="446" Style="{StaticResource BodyTextBlockStyle}" Visibility="Collapsed" Margin="12,0,0,0" />
</Grid>
</Grid>
</UserControl>

Просмотреть файл

@ -1,9 +1,12 @@
using IoTCoreDefaultApp.Utils;
using IoTCoreDefaultApp.Presenters;
using IoTCoreDefaultApp.Utils;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Threading.Tasks;
using Windows.ApplicationModel.Resources;
using Windows.Devices.WiFi;
using Windows.Foundation.Metadata;
using Windows.Security.Credentials;
using Windows.UI.Core;
using Windows.UI.Xaml;
@ -15,37 +18,41 @@ namespace IoTCoreDefaultApp
{
public sealed partial class NetworkListControl : UserControl
{
private NetworkPresenter networkPresenter = new NetworkPresenter();
private bool ConnectAutomatically = true;
private string CurrentPassword = string.Empty;
public event EventHandler<EventArgs> NetworkConnected;
public ObservableCollection<WifiListViewItemPresenter> WifiListViewItems = new ObservableCollection<WifiListViewItemPresenter>();
public NetworkListControl()
{
this.InitializeComponent();
this.DataContext = LanguageManager.GetInstance();
WifiListView.ItemsSource = WifiListViewItems;
}
private void EnableView(bool enable)
private void EnableView(bool enable, bool enableListView)
{
RefreshButton.IsEnabled = enable;
WifiListView.IsEnabled = enable;
RefreshButton.Visibility = enable? Visibility.Visible : Visibility.Collapsed;
RefreshProgressRing.Visibility = enable ? Visibility.Collapsed : Visibility.Visible;
WifiListView.IsEnabled = enableListView;
}
private async void RefreshButton_Click(object sender, RoutedEventArgs e)
{
await RecreateWifiNetworkListAsync();
try
{
await RefreshWifiListViewItemsAsync(false);
}
catch (Exception ex)
{
Log.Trace(ex.ToString());
throw;
}
}
public async Task SetupNetworkAsync()
{
SetupEthernet();
await RecreateWifiNetworkListAsync();
}
private void SetupEthernet()
public void SetupDirectConnection()
{
var ethernetProfile = NetworkPresenter.GetDirectConnectionName();
@ -61,46 +68,47 @@ namespace IoTCoreDefaultApp
}
}
private async Task RecreateWifiNetworkListAsync()
public async Task RefreshWifiListViewItemsAsync(bool refreshIfNeeded)
{
if (await networkPresenter.WifiIsAvailable())
if (await App.NetworkPresenter.WifiIsAvailable())
{
EnableView(false);
bool isRefreshNeeded = App.NetworkPresenter.IsRefreshNeeded();
EnableView(false, false);
ObservableCollection<WiFiAvailableNetwork> networks;
try
{
networks = new ObservableCollection<WiFiAvailableNetwork>(await networkPresenter.GetAvailableNetworks());
var networks = await App.NetworkPresenter.GetAvailableNetworks(refreshIfNeeded);
if (networks.Count > 0)
{
var connectedNetwork = App.NetworkPresenter.GetCurrentWifiNetwork();
if (connectedNetwork != null)
{
networks.Remove(connectedNetwork);
networks.Insert(0, connectedNetwork);
}
WifiListView.ItemsSource = WifiListViewItems = new ObservableCollection<WifiListViewItemPresenter>(networks);
var item = SwitchToItemState(connectedNetwork, WifiConnectedState, true);
if (item != null)
{
WifiListView.SelectedItem = item;
}
NoWifiFoundText.Visibility = Visibility.Collapsed;
WifiListView.Visibility = Visibility.Visible;
EnableView(true, true);
return;
}
}
catch (Exception e)
{
Log.Write(String.Format("Error scanning: 0x{0:X}: {1}", e.HResult, e.Message));
NoWifiFoundText.Text = e.Message;
NoWifiFoundText.Visibility = Visibility.Visible;
EnableView(true);
return;
}
if (networks.Count > 0)
{
var connectedNetwork = networkPresenter.GetCurrentWifiNetwork();
if (connectedNetwork != null)
{
networks.Remove(connectedNetwork);
networks.Insert(0, connectedNetwork);
WifiListView.ItemsSource = networks;
SwitchToItemState(connectedNetwork, WifiConnectedState, true);
}
else
{
WifiListView.ItemsSource = networks;
}
NoWifiFoundText.Visibility = Visibility.Collapsed;
WifiListView.Visibility = Visibility.Visible;
EnableView(true);
EnableView(true, true);
return;
}
}
@ -111,7 +119,7 @@ namespace IoTCoreDefaultApp
private void WifiListView_ItemClick(object sender, ItemClickEventArgs e)
{
var connectedNetwork = networkPresenter.GetCurrentWifiNetwork();
var connectedNetwork = App.NetworkPresenter.GetCurrentWifiNetwork();
var item = e.ClickedItem;
if (connectedNetwork == item)
{
@ -122,16 +130,22 @@ namespace IoTCoreDefaultApp
private void WifiListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var listView = sender as ListView;
var connectedNetwork = App.NetworkPresenter.GetCurrentWifiNetwork();
foreach (var item in e.RemovedItems)
{
SwitchToItemState(item, WifiInitialState, true);
if (connectedNetwork == item)
{
SwitchToItemState(item, WifiConnectedState, true);
}
else
{
SwitchToItemState(item, WifiInitialState, true);
}
}
foreach (var item in e.AddedItems)
{
ConnectAutomatically = true;
var connectedNetwork = networkPresenter.GetCurrentWifiNetwork();
if (connectedNetwork == item)
{
SwitchToItemState(connectedNetwork, WifiConnectedMoreOptions, true);
@ -141,105 +155,184 @@ namespace IoTCoreDefaultApp
SwitchToItemState(item, WifiConnectState, true);
}
}
WifiListView.ScrollIntoView(WifiListView.SelectedItem);
}
private async void ConnectButton_Clicked(object sender, RoutedEventArgs e)
private async void ConnectButton_Click(object sender, RoutedEventArgs e)
{
try
{
EnableView(false);
EnableView(false, true);
var button = sender as Button;
var network = button.DataContext as WiFiAvailableNetwork;
var network = button.DataContext as WifiListViewItemPresenter;
if (NetworkPresenter.IsNetworkOpen(network))
{
await ConnectToWifiAsync(network, null, Window.Current.Dispatcher);
}
else if (network.IsEapAvailable)
{
SwitchToItemState(network, WifiEapPasswordState, false);
}
else
{
SwitchToItemState(network, WifiPasswordState, false);
}
}
catch(Exception ex)
{
Log.Trace(ex.ToString());
throw;
}
finally
{
EnableView(true);
EnableView(true, true);
}
}
private async Task ConnectToWifiAsync(WiFiAvailableNetwork network, PasswordCredential credential, CoreDispatcher dispatcher)
private async Task OnConnected(WifiListViewItemPresenter network, WiFiConnectionStatus status, CoreDispatcher dispatcher)
{
if (status == WiFiConnectionStatus.Success)
{
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
var itemLocation = WifiListViewItems.IndexOf(network);
// don't move if index is -1 or 0
if (itemLocation > 0)
{
// make sure first network doesn't also show connected
SwitchToItemState(WifiListViewItems[0], WifiInitialState, true);
// Show current connected network at top of list in connected state
WifiListViewItems.Move(itemLocation, 0);
}
var item = SwitchToItemState(network, WifiConnectedState, true);
if (item != null)
{
item.IsSelected = true;
}
});
NetworkConnected?.Invoke(this, new EventArgs());
}
else
{
var resourceLoader = ResourceLoader.GetForCurrentView();
network.Message = resourceLoader.GetString(status.ToString() + "Text");
network.IsMessageVisible = true;
SwitchToItemState(network, WifiConnectState, true);
}
}
private async Task ConnectToWifiAsync(WifiListViewItemPresenter network, PasswordCredential credential, CoreDispatcher dispatcher)
{
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
SwitchToItemState(network, WifiConnectingState, false);
});
var didConnect = credential == null ?
networkPresenter.ConnectToNetwork(network, ConnectAutomatically) :
networkPresenter.ConnectToNetworkWithPassword(network, ConnectAutomatically, credential);
DataTemplate nextState = (await didConnect) ? WifiConnectedState : WifiInitialState;
bool isConnected = (nextState == WifiConnectedState);
await dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
Task<WiFiConnectionStatus> didConnect = null;
if (network.IsEapAvailable)
{
var list = WifiListView.ItemsSource as ObservableCollection<WiFiAvailableNetwork>;
var itemLocation = list.IndexOf(network);
if (0 != itemLocation && isConnected)
{
list.Move(itemLocation, 0);
}
var item = SwitchToItemState(network, nextState, true);
if (item != null)
{
item.IsSelected = true;
}
});
if (isConnected)
{
NetworkConnected?.Invoke(this, new EventArgs());
didConnect = (credential == null) ?
App.NetworkPresenter.ConnectToNetwork(network, network.ConnectAutomatically) :
App.NetworkPresenter.ConnectToNetworkWithPassword(network, network.ConnectAutomatically, credential);
}
else
{
didConnect = (credential == null) ?
App.NetworkPresenter.ConnectToNetwork(network, network.ConnectAutomatically) :
App.NetworkPresenter.ConnectToNetworkWithPassword(network, network.ConnectAutomatically, credential);
}
WiFiConnectionStatus status = await didConnect;
await OnConnected(network, status, dispatcher);
}
private void DisconnectButton_Clicked(object sender, RoutedEventArgs e)
{
var button = sender as Button;
var network = button.DataContext as WiFiAvailableNetwork;
var connectedNetwork = networkPresenter.GetCurrentWifiNetwork();
if (network == connectedNetwork)
try
{
networkPresenter.DisconnectNetwork(network);
var item = SwitchToItemState(network, WifiInitialState, true);
item.IsSelected = false;
var button = sender as Button;
var network = button.DataContext as WifiListViewItemPresenter;
var connectedNetwork = App.NetworkPresenter.GetCurrentWifiNetwork();
if (network == connectedNetwork)
{
App.NetworkPresenter.DisconnectNetwork(network);
var item = SwitchToItemState(network, WifiInitialState, true);
item.IsSelected = false;
}
}
catch (Exception ex)
{
Log.Trace(ex.ToString());
throw;
}
}
private async void NextButton_Clicked(object sender, RoutedEventArgs e)
{
var button = sender as Button;
PasswordCredential credential;
if (string.IsNullOrEmpty(CurrentPassword))
try
{
credential = null;
}
else
{
credential = new PasswordCredential()
EnableView(false, true);
var button = sender as Button;
PasswordCredential credential;
var network = button.DataContext as WifiListViewItemPresenter;
if (network != null)
{
Password = CurrentPassword
};
}
if (string.IsNullOrEmpty(network.Password))
{
credential = null;
}
else
{
credential = new PasswordCredential();
if (network.UsePassword)
{
if (!String.IsNullOrEmpty(network.Domain))
{
credential.Resource = network.Domain;
}
credential.UserName = network.UserName ?? "";
credential.Password = network.Password ?? "";
}
else
{
credential.Password = network.Password;
}
}
var network = button.DataContext as WiFiAvailableNetwork;
await ConnectToWifiAsync(network, credential, Window.Current.Dispatcher);
await ConnectToWifiAsync(network, credential, Window.Current.Dispatcher);
}
}
catch (Exception ex)
{
Log.Trace(ex.ToString());
throw;
}
finally
{
EnableView(true, true);
}
}
private void CancelButton_Clicked(object sender, RoutedEventArgs e)
{
var button = sender as Button;
var item = SwitchToItemState(button.DataContext, WifiInitialState, false);
item.IsSelected = false;
try
{
// Cancels the UI state but not the connection attempt
var button = sender as Button;
var item = SwitchToItemState(button.DataContext, WifiConnectState, false);
}
catch (Exception ex)
{
Log.Trace(ex.ToString());
throw;
}
}
private ListViewItem SwitchToItemState(object dataContext, DataTemplate template, bool forceUpdate)
@ -253,22 +346,10 @@ namespace IoTCoreDefaultApp
{
item.ContentTemplate = template;
}
return item;
}
private void ConnectAutomaticallyCheckBox_Changed(object sender, RoutedEventArgs e)
{
var checkbox = sender as CheckBox;
ConnectAutomatically = checkbox.IsChecked ?? false;
}
private void WifiPasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
var passwordBox = sender as PasswordBox;
CurrentPassword = passwordBox.Password;
}
private void WifiPasswordBox_Loaded(object sender, RoutedEventArgs e)
{
var passwordBox = sender as PasswordBox;
@ -278,5 +359,32 @@ namespace IoTCoreDefaultApp
}
}
private async void PushButtonConnect_Click(object sender, RoutedEventArgs e)
{
try
{
EnableView(false, true);
var button = sender as Button;
var network = button.DataContext as WifiListViewItemPresenter;
if (network != null)
{
if (ApiInformation.IsApiContractPresent("Windows.Foundation.UniversalApiContract", 5, 0))
{
var didConnect = await network.Adapter.ConnectAsync(network.AvailableNetwork, network.ConnectAutomatically? WiFiReconnectionKind.Automatic : WiFiReconnectionKind.Manual, null, String.Empty, WiFiConnectionMethod.WpsPushButton).AsTask<WiFiConnectionResult>();
await OnConnected(network, didConnect.ConnectionStatus, Window.Current.Dispatcher);
}
}
}
catch (Exception ex)
{
Log.Trace(ex.ToString());
throw;
}
finally
{
EnableView(true, true);
}
}
}
}

Просмотреть файл

@ -1,6 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using Windows.Storage;
@ -10,6 +10,7 @@ namespace IoTCoreDefaultApp.Utils
{
static private StorageFile _file;
static private SemaphoreSlim _semaphore = new SemaphoreSlim(1);
static public bool TraceEnterAndLeave = true;
public static void Write(string message)
{
@ -24,5 +25,33 @@ namespace IoTCoreDefaultApp.Utils
FileIO.AppendTextAsync(_file, messageWithTimestamp).AsTask().Wait();
Debug.Write(messageWithTimestamp);
}
[Conditional("DEBUG")]
public static void Trace(string message, [CallerMemberName] string memberName = "")
{
string time = DateTime.Now.ToString("HH:mm:ss.fff");
Debug.WriteLine($"{time} [{memberName}] {message}");
}
[Conditional("DEBUG")]
public static void Enter(string message="", [CallerMemberName] string memberName = "")
{
if (TraceEnterAndLeave)
{
string time = DateTime.Now.ToString("HH:mm:ss.fff");
Debug.WriteLine($"{time} [{memberName}] ENTER {message}");
}
}
[Conditional("DEBUG")]
public static void Leave(string message = "", [CallerMemberName] string memberName = "")
{
if (TraceEnterAndLeave)
{
string time = DateTime.Now.ToString("HH:mm:ss.fff");
Debug.WriteLine($"{time} [{memberName}] LEAVE {message}");
}
}
}
}

Просмотреть файл

@ -45,6 +45,7 @@ namespace IoTCoreDefaultApp
public MainPage()
{
Log.Enter();
this.InitializeComponent();
// This is a static public property that allows downstream pages to get a handle to the MainPage instance
@ -63,6 +64,7 @@ namespace IoTCoreDefaultApp
this.Loaded += async (sender, e) =>
{
Log.Enter("MainPage Loaded");
await MainPageDispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
{
UpdateBoardInfo();
@ -70,8 +72,9 @@ namespace IoTCoreDefaultApp
UpdateConnectedDevices();
UpdatePackageVersion();
});
Log.Leave();
};
Log.Leave();
}
private async void UpdateMakerImageSecurityNotice()

Просмотреть файл

@ -35,7 +35,7 @@
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
@ -51,9 +51,7 @@
<TextBlock Text="{Binding [OOBENetworkTitleText]}" Style="{StaticResource BodyTextBlockStyle}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,14,0,0"/>
</StackPanel>
<ScrollViewer Grid.Column="1" Grid.Row="2">
<local:NetworkListControl x:Name="NetworkGrid"/>
</ScrollViewer>
<local:NetworkListControl Grid.Column="1" Grid.Row="2" x:Name="NetworkControl" Margin="24"/>
<HyperlinkButton Grid.Column="1" Grid.Row="3" x:Name="SkipButton" HorizontalAlignment="Left" VerticalAlignment="Bottom" Click="SkipButton_Clicked" HorizontalContentAlignment="Left">
<TextBlock Text="{Binding [SkipStepText]}"/>

Просмотреть файл

@ -1,7 +1,9 @@
// Copyright (c) Microsoft. All rights reserved.
using IoTCoreDefaultApp.Utils;
using System;
using System.Threading.Tasks;
using Windows.Networking.Connectivity;
using Windows.UI.Core;
using Windows.UI.Xaml;
@ -17,6 +19,7 @@ namespace IoTCoreDefaultApp
public sealed partial class OOBENetwork : Page
{
private CoreDispatcher OOBENetworkPageDispatcher;
private bool connected = false;
public OOBENetwork()
{
@ -24,7 +27,7 @@ namespace IoTCoreDefaultApp
OOBENetworkPageDispatcher = Window.Current.Dispatcher;
NetworkInformation.NetworkStatusChanged += NetworkInformation_NetworkStatusChanged;
NetworkGrid.NetworkConnected += NetworkGrid_NetworkConnected;
NetworkControl.NetworkConnected += NetworkGrid_NetworkConnected;
this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled;
@ -34,28 +37,37 @@ namespace IoTCoreDefaultApp
this.Loaded += async (sender, e) =>
{
await OOBENetworkPageDispatcher.RunAsync(CoreDispatcherPriority.Low, async () => {
await NetworkGrid.SetupNetworkAsync();
NetworkControl.SetupDirectConnection();
await NetworkControl.RefreshWifiListViewItemsAsync(true);
});
};
}
private async void NetworkInformation_NetworkStatusChanged(object sender)
{
await OOBENetworkPageDispatcher.RunAsync(CoreDispatcherPriority.Low, async () =>
Log.Enter();
if (!connected)
{
await NetworkGrid.SetupNetworkAsync();
});
await OOBENetworkPageDispatcher.RunAsync(CoreDispatcherPriority.Low, () =>
{
NetworkControl.SetupDirectConnection();
});
}
Log.Leave();
}
private async void NetworkGrid_NetworkConnected(object sender, EventArgs e)
{
Log.Enter();
connected = true;
await OOBENetworkPageDispatcher.RunAsync(CoreDispatcherPriority.Normal, async () =>
{
await CortanaHelper.LaunchCortanaToConsentPageAsyncIfNeeded();
NavigationUtils.NavigateToScreen(typeof(MainPage));
});
Log.Leave();
}
private void BackButton_Clicked(object sender, RoutedEventArgs e)
{
NavigationUtils.GoBack();

Просмотреть файл

@ -3,7 +3,6 @@
using System;
using System.Globalization;
using Windows.Foundation;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
@ -20,6 +19,8 @@ namespace IoTCoreDefaultApp
private LanguageManager languageManager;
private DispatcherTimer timer;
private DispatcherTimer countdown;
private NetworkPresenter networkPresenter = new NetworkPresenter();
public OOBEWelcome()
@ -241,7 +242,6 @@ namespace IoTCoreDefaultApp
private async void NextButton_Clicked(object sender, RoutedEventArgs e)
{
var networkPresenter = new NetworkPresenter();
var wifiAvailable = networkPresenter.WifiIsAvailable();
SetPreferences();
Type nextScreen;

Просмотреть файл

@ -182,9 +182,7 @@
</Grid>
</ScrollViewer>
<ScrollViewer x:Name="NetworkGrid" Grid.Column="2" Grid.Row="1" >
<local:NetworkListControl x:Name="NetworkControl" Grid.Column="2" Grid.Row="1" />
</ScrollViewer>
<local:NetworkListControl x:Name="NetworkControl" Margin="24,25,24,25" Grid.Column="2" Grid.Row="1"/>
<Grid x:Name="BluetoothGrid" Margin="24,25,24,25" Grid.Column="2" Grid.Row="1">
<Grid.RowDefinitions>

Просмотреть файл

@ -513,7 +513,7 @@ namespace IoTCoreDefaultApp
switch (itemName)
{
case "PreferencesListViewItem":
NetworkGrid.Visibility = Visibility.Collapsed;
NetworkControl.Visibility = Visibility.Collapsed;
BluetoothGrid.Visibility = Visibility.Collapsed;
CortanaGrid.Visibility = Visibility.Collapsed;
@ -528,16 +528,17 @@ namespace IoTCoreDefaultApp
BluetoothGrid.Visibility = Visibility.Collapsed;
CortanaGrid.Visibility = Visibility.Collapsed;
if (NetworkGrid.Visibility == Visibility.Collapsed)
if (NetworkControl.Visibility == Visibility.Collapsed)
{
NetworkGrid.Visibility = Visibility.Visible;
NetworkControl.Visibility = Visibility.Visible;
NetworkListView.IsSelected = true;
await NetworkControl.SetupNetworkAsync();
NetworkControl.SetupDirectConnection();
await NetworkControl.RefreshWifiListViewItemsAsync(true);
}
break;
case "BluetoothListViewItem":
BasicPreferencesGridView.Visibility = Visibility.Collapsed;
NetworkGrid.Visibility = Visibility.Collapsed;
NetworkControl.Visibility = Visibility.Collapsed;
CortanaGrid.Visibility = Visibility.Collapsed;
if (BluetoothGrid.Visibility == Visibility.Collapsed)
@ -556,7 +557,7 @@ namespace IoTCoreDefaultApp
break;
case "CortanaListViewItem":
BasicPreferencesGridView.Visibility = Visibility.Collapsed;
NetworkGrid.Visibility = Visibility.Collapsed;
NetworkControl.Visibility = Visibility.Collapsed;
BluetoothGrid.Visibility = Visibility.Collapsed;
if (CortanaGrid.Visibility == Visibility.Collapsed)
@ -815,11 +816,11 @@ namespace IoTCoreDefaultApp
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private async void InboundPairingRequestedHandler(
private void InboundPairingRequestedHandler(
DeviceInformationCustomPairing sender,
DevicePairingRequestedEventArgs args)
{
PairingRequestedHandler(inboundContext, args);
PairingRequestedHandlerAsync(inboundContext, args).Wait();
}
/// <summary>
@ -827,11 +828,11 @@ namespace IoTCoreDefaultApp
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private async void OutboundPairingRequestedHandler(
private void OutboundPairingRequestedHandler(
DeviceInformationCustomPairing sender,
DevicePairingRequestedEventArgs args)
{
PairingRequestedHandler(outboundContext, args);
PairingRequestedHandlerAsync(outboundContext, args).Wait();
}
@ -840,7 +841,7 @@ namespace IoTCoreDefaultApp
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
private async void PairingRequestedHandler(
private async Task PairingRequestedHandlerAsync(
PairingContext pairingContext,
DevicePairingRequestedEventArgs args)
{

Просмотреть файл

@ -3,6 +3,7 @@
using SDKTemplate;
using System;
using System.Collections.Concurrent;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
@ -130,17 +131,27 @@ namespace WiFiConnect
rootPage.NotifyUser(string.Format("Network Report Timestamp: {0}", report.Timestamp), NotifyType.StatusMessage);
ResultCollection.Clear();
ConcurrentDictionary<string, WiFiNetworkDisplay> dictionary = new ConcurrentDictionary<string, WiFiNetworkDisplay>();
foreach (var network in report.AvailableNetworks)
{
var item = new WiFiNetworkDisplay(network, firstAdapter);
if (!String.IsNullOrEmpty(network.Ssid))
{
var item = new WiFiNetworkDisplay(network, firstAdapter);
dictionary.TryAdd(network.Ssid, item);
}
}
var values = dictionary.Values;
foreach (var item in values)
{
/*await*/ item.UpdateAsync();
if (IsConnected(network))
if (IsConnected(item.AvailableNetwork))
{
ResultCollection.Insert(0, item);
ResultsListView.SelectedItem = ResultsListView.Items[0];
ResultsListView.ScrollIntoView(ResultsListView.SelectedItem);
SwitchToItemState(network, WifiConnectedState, false);
SwitchToItemState(item.AvailableNetwork, WifiConnectedState, false);
}
else
{