2

我尝试实现(在WPFC#中)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;
        }
    }

}


它运作良好,但有两个问题:

  1. 检查连接需要一些时间,所以我认为我应该在新线程中进行(如果我错了,请告诉我原因)
  2. 更重要的是——它只检查一次与谷歌的连接,当程序开始运行时(尽管我使用绑定,所以我希望会有持续的连接监控)

我应该如何解决这个问题?
我想要持续监控连接,这样当我断开互联网连接时,Ellipse控件会改变它的颜色。

4

2 回答 2

2

你必须稍微改变你的架构。
您不能使用线程IValueConverter来避免锁定 UI。在从IValueConverter.

您需要创建一个HasConnection属性来将椭圆颜色绑定到。然后,您可以在另一个线程中运行连接检查。最好通过使用BackgroundWorker. HasConnection检查完成后,应更新该属性。然后,您可以使用计时器并定期检查您的连接,并HasConnection在每次检查后更新。

编辑
您还可以监视NetworkChange.NetworkAvailabilityChanged事件以了解本地网络连接何时启动或关闭。但是,您希望确保您可以实际连接到您的目标,您应该保留旧的CheckConnection,但CheckConnection在启动时调用,当网络可用性发生变化时并定期在计时器上调用。

于 2012-09-02T18:18:12.100 回答
0

使用background worker在后台监控,使用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());
}
于 2012-09-17T00:05:22.650 回答