我尝试实施(在 WPF , C#)Ellipse
控件,根据与google.com的连接更改颜色。如果与 Google 有连接,则椭圆为绿色;否则它是红色的。
我用这种方式编码:
XAML代码
<Window.Resources>
<l:InternetConnectionToBrushConverter x:Key="InternetConnectionConverter" />
</Window.Resources>
<Grid>
<DockPanel LastChildFill="True">
<StatusBar Height="23" Name="statusBar1" VerticalAlignment="Bottom" DockPanel.Dock="Bottom">
<Label Content="Google connection:" Name="label1" FontSize="10" Padding="3" />
<Ellipse Name="ellipse1" Stroke="Black" Width="10" Height="10" Fill="{Binding Converter={StaticResource InternetConnectionConverter}}" Margin="0,4,0,0" />
</StatusBar>
</DockPanel>
</Grid>
和C#后置代码(值转换器和函数检查连接):
public class InternetConnectionToBrushConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(Brush))
throw new InvalidOperationException("The target must be a Brush!");
return CheckConnection("http://www.google.com/") == true ? Brushes.Green : Brushes.Red;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
/// <summary>
/// Checks connection to specified URL.
/// </summary>
/// <param name="URL"></param>
/// <returns><b>True</b> if there is connection. Else <b>false</b>.</returns>
private bool CheckConnection(String URL)
{
try
{
HttpWebRequest request = WebRequest.Create(URL) as HttpWebRequest;
request.Timeout = 15000;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
return response.StatusCode == HttpStatusCode.OK ? true : false;
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
return false;
}
}
}
它运作良好但存在两个问题:
我该如何解决这个问题?
我希望有持续的连接监控,这样当我断开互联网连接时,Ellipse
控件将改变其颜色。
答案 0 :(得分:2)
你必须稍微改变你的架构
您无法在IValueConverter
中使用线程来避免锁定UI。在从IValueConverter
返回之前,您仍需要等待线程完成。
您需要创建一个HasConnection
属性来将椭圆颜色绑定到。然后,您可以在另一个线程中运行连接检查。最好使用BackgroundWorker
。检查完成后,应更新HasConnection
属性。然后,您可以定期使用计时器并检查连接,并在每次检查后更新HasConnection
。
修改强>
您还可以监视NetworkChange.NetworkAvailabilityChanged
事件,以了解本地网络连接何时启动或关闭。但是,如果您希望确保实际连接到目标,则应保留旧的CheckConnection
,但在网络可用性发生变化时定期在计时器上启动时调用CheckConnection
。
答案 1 :(得分:0)
使用后台工作程序在后台监视,使用ReportProgress获取当前状态
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Get the BackgroundWorker that raised this event.
BackgroundWorker worker = sender as BackgroundWorker;
bool connected = false;
string url = "https://www.google.com/";
while (!worker.CancellationPending)
{
try
{
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Timeout = 15000;
request.Credentials = CredentialCache.DefaultNetworkCredentials;
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
connected = (response.StatusCode == HttpStatusCode.OK);
backgroundWorker1.ReportProgress(10, connected);
Thread.Sleep(1000);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
e.Cancel = true;
e.Result = "cancelled";
//return false;
}
}
e.Result = connected;
}
private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
this.tbResult.Text = e.ProgressPercentage.ToString();
System.Diagnostics.Debug.WriteLine(e.UserState.ToString());
}