2014-01-15 3 views
0

Прежде всего - пожалуйста, извините мое бедное произношение. Я программирую wpf-validator для excelsheet, и пока эта программа получает информацию от google, она должна показывать прогресс на панели прогресса. Я читал много статей в Интернете о многопоточности и фоновой работе, но я думаю, что ничто не может мне помочь.Как управлять потоком для обновления графического интерфейса?

Вот мой GUI

<Window x:Class="DatenValidierung.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="570" Width="825" ResizeMode="NoResize"> 
    <Grid Background="Black"> 
     <Button Foreground="White" Background="Black" Name="exit" Content="Exit" HorizontalAlignment="Left" Margin="714,484,0,0" VerticalAlignment="Top" Width="94" Click="exit_Click" Height="27"/> 
     <Button Foreground="White" Background="Black" Name="open" Content="Excel öffnen" HorizontalAlignment="Left" Margin="10,460,0,0" VerticalAlignment="Top" Width="88" Click="open_Click" /> 
     <DataGrid Name="dg1" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="445" Width="798" AutoGenerateColumns="False" IsReadOnly="True"> 
      <DataGrid.Columns> 
       <DataGridTextColumn Binding="{Binding SubCategory}" Header="Kat" Width="90" /> 
       <DataGridTextColumn Binding="{Binding Title}" Header="Title" Width="80" /> 
       <DataGridTextColumn Binding="{Binding InfoText}" Header="Info" Width="80" /> 
       <DataGridTextColumn Binding="{Binding Domain}" Header="Domain" Width="60" /> 
       <DataGridTextColumn Binding="{Binding City}" Header="City" Width="50" /> 
       <DataGridTextColumn Binding="{Binding Zipcode}" Header="Zip" Width="50" /> 
       <DataGridTextColumn Binding="{Binding Longitude}" Header="Long" Width="50" /> 
       <DataGridTextColumn Binding="{Binding Latitude}" Header="Lat" Width="50" /> 
       <DataGridTextColumn Binding="{Binding Telefon}" Header="Tel" Width="50" /> 
       <DataGridTextColumn Binding="{Binding Mail}" Header="Mail" Width="50" /> 
       <DataGridTextColumn Binding="{Binding Address}" Header="Adresse" Width="50" /> 
      </DataGrid.Columns> 
     </DataGrid> 
     <Button Content="Hochladen" Background="Black" Foreground="White" Name="upload" Click="upload_Click" HorizontalAlignment="Left" Margin="10,508,0,0" VerticalAlignment="Top" Width="88"/> 
     <Button Content="google-Daten" Name="check" Background="Black" Foreground="White" HorizontalAlignment="Left" Margin="10,484,0,0" VerticalAlignment="Top" Width="88" Click="check_Click"/> 
     <ProgressBar Value="{Binding Path=ProgressValue}" HorizontalAlignment="Left" Height="24" Margin="270,460,0,0" VerticalAlignment="Top" Width="200" Name="pb1"/> 
     <Label Name="progressLabel" Foreground="White" TextBlock.TextAlignment="Center" Content="" HorizontalAlignment="Left" Margin="320,489,0,0" VerticalAlignment="Top" Width="100"/> 

    </Grid> 
</Window> 

А вот мой CodeBehind

using System; 
    using System.Collections.Generic; 
    using System.Linq; 
    using System.Text; 
    using System.Threading.Tasks; 
    using System.Windows; 
    using System.Windows.Forms; 
    using System.Windows.Controls; 
    using System.Windows.Data; 
    using System.Windows.Documents; 
    using System.Windows.Input; 
    using System.Windows.Media; 
    using System.Windows.Media.Imaging; 
    using System.Windows.Navigation; 
    using System.Windows.Shapes; 
    using Excel = Microsoft.Office.Interop.Excel; 
    using System.Data.OleDb; 
    using System.Data; 
    using System.Globalization; 
    using System.ComponentModel; 
    using System.Threading; 
    using System.Net; 
    using System.Xml.Linq; 
    using DatenValidierung.ServiceReference1; 



    namespace DatenValidierung 
    { 
     public partial class MainWindow : Window 
     { 
      int progressCounter = 0; 
      List<Location> locationList = new List<Location>(); 

      public MainWindow() 
      { 
       InitializeComponent();   
      } 

      double progressValue; 
      public double ProgressValue 
      { 
       get { return progressValue; } 
       set 
       { 
        if (progressValue != value) 
        { 
         progressValue = value; 
         OnPropertyChanged("ProgressValue"); 
        } 
       } 
      } 

      public event PropertyChangedEventHandler PropertyChanged; 
      public void OnPropertyChanged(string property_name) 
      { 
       if (PropertyChanged != null) 
        PropertyChanged(this, new PropertyChangedEventArgs(property_name)); 
      } 

      public static DataTable ReadExcelData(string filePath) 
      { 
       System.Data.DataTable dtExcel = new System.Data.DataTable(); 
       dtExcel.TableName = "MyExcelData"; 
       bool hasHeaders = false; 
       string strConn = string.Empty; 
       string HDR = hasHeaders ? "Yes" : "No"; 
       if (filePath.Substring(filePath.LastIndexOf('.')).ToLower() == ".xlsx") 
       { 
        strConn = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=\"Excel 12.0;HDR=" + HDR + ";IMEX=0\""; 
       } 
       else 
       { 
        strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties=\"Excel 8.0;HDR=" + HDR + ";IMEX=0\""; 
       } 
       //string SourceConstr = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source='MyExcelFilePath';Extended Properties= 'Excel 8.0;HDR=Yes;IMEX=1'"; 
       OleDbConnection con = new OleDbConnection(strConn); 
       con.Open(); 
       DataTable schemaTable = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); 
       DataRow schemaRow = schemaTable.Rows[0]; 
       string sheet = schemaRow["TABLE_NAME"].ToString(); 
       string query = "SELECT * FROM [" + sheet + "]"; 
       OleDbDataAdapter data = new OleDbDataAdapter(query, con); 
       data.Fill(dtExcel); 

       return dtExcel; 
      } 

      private void open_Click(object sender, RoutedEventArgs e) 
      { 
       var dataFromExcel = new DataTable(); 
       string ausgabeTemp = String.Empty; 
       OpenFileDialog BrowserFileDialog = new OpenFileDialog(); 
       BrowserFileDialog.Title = ""; 
       BrowserFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);    
       BrowserFileDialog.FilterIndex = 1; 
       BrowserFileDialog.RestoreDirectory = true; 
       if (BrowserFileDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK) 
       {     
        dataFromExcel = ReadExcelData(BrowserFileDialog.FileName); 
       } 

       var liste = dataFromExcel.AsEnumerable().ToList(); 

       int k = 0; 
       for (int i = 0; i < liste.Count; i++) 
       {     
        Location loc = new Location(); 
        loc.SubCategory = liste[k].ItemArray[0].ToString(); 
        loc.City = liste[k].ItemArray[1].ToString(); 
        loc.Zipcode = liste[k].ItemArray[2].ToString(); 
        loc.Address = liste[k].ItemArray[3].ToString(); 
        loc.Telefon = liste[k].ItemArray[4].ToString(); 
        loc.Mail = liste[k].ItemArray[5].ToString(); 
        loc.Domain = liste[k].ItemArray[6].ToString(); 
        loc.SubCategory = liste[k].ItemArray[7].ToString(); 
        loc.InfoText = liste[k].ItemArray[8].ToString(); 
        locationList.Add(loc); 
        k++; 
       } 
       pb1.Maximum = k; 
       pb1.Minimum = 0; 
       var fred = new Thread(updateProgressBar); 
       fred.IsBackground = true; 
       fred.Start(); 
       FormatList(locationList); 

      } 

      public void updateProgressBar() 
      { 
       ProgressValue = ((double)progressCounter * 100)/locationList.Count ; 
       progressLabel.Content = ProgressValue + "/100"; 
      } 

      public List<Location> FormatList(List<Location> locationList) 
      { 


       var locList = locationList; 
       locList = FormatLocationForDB(locList); 
       for (int i = 0; i < locList.Count; i++) 
       { 
        if (locList[i].Latitude == 0 || locList[0].Longitude == 0) 
        { 
         locList[i] = GetSingleFormatForDB(locList[i]); 
        } 
       } 
       return locList; 
      } 

      public List<Location> FormatLocationForDB(object o) 
      { 
       progressCounter = 0; 
       var locList = new List<Location>(); 
       foreach (Location currentLocation in locationList) 
       { 
        Thread.Sleep(50); 
        // System.Threading.Thread.Sleep(200); 
        string address = currentLocation.Address + ", " + currentLocation.City; 
        var requestUri = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=false", Uri.EscapeDataString(address)); 
        var request = WebRequest.Create(requestUri); 
        var response = request.GetResponse(); 
        var xdoc = XDocument.Load(response.GetResponseStream()); 


        try 
        { 
         var result = xdoc.Element("GeocodeResponse").Element("result"); 
         var locationElement = result.Element("geometry").Element("location"); 
         currentLocation.Latitude = (float)(locationElement.Element("lat")); 
         currentLocation.Longitude = (float)(locationElement.Element("lng")); 
        } 
        catch (Exception x) 
        { 

        } 
        dg1.Items.Add(currentLocation); 
        dg1.InvalidateVisual(); 
        progressCounter++;    
        locList.Add(currentLocation); 
       } 
       return locList; 

      } 

      public Location GetSingleFormatForDB(Location location) 
      { 
       string address = location.Address + ", " + location.City; 
       var requestUri = string.Format("http://maps.googleapis.com/maps/api/geocode/xml?address={0}&sensor=false", Uri.EscapeDataString(address)); 
       var request = WebRequest.Create(requestUri); 
       var response = request.GetResponse(); 
       var xdoc = XDocument.Load(response.GetResponseStream()); 
       try 
       { 
        var result = xdoc.Element("GeocodeResponse").Element("result"); 
        var locationElement = result.Element("geometry").Element("location"); 
        location.Latitude = (float)(locationElement.Element("lat")); 
        location.Longitude = (float)(locationElement.Element("lng")); 
       } 
       catch (Exception x) 
       { 

       } 
       return location; 
      } 

      public static void InsertLocationListToDB(Location location) 
      { 
       Service1Client wcf = new Service1Client(); 
       try 
       { 
        wcf.ClientCredentials.UserName.UserName = "admin2"; 
        wcf.ClientCredentials.UserName.Password = "123test123!"; 
        wcf.AddLocationFromListAsync(
         location.SubCategory, 
         location.Title, 
         location.InfoText, 
         location.Domain, 
         location.City, 
         location.Zipcode, 
         (float)location.Longitude, 
         (float)location.Latitude, 
         location.Telefon, 
         location.Mail, 
         location.Address 
         ); 
       } 
       catch (Exception x) 
       { 
       } 
      } 

      private void upload_Click(object sender, RoutedEventArgs e) 
      { 
       if (locationList.Count > 0 || locationList != null) 
       { 
        dg1.Items.Clear(); 
        foreach (Location l in locationList) 
        { 
         if (l.Latitude != 0 && l.Longitude != 0) 
         { 
          locationList.Remove(l); 
         } 
         dg1.Items.Add(l); 
        } 
       } 

      } 

      private void check_Click(object sender, RoutedEventArgs e) 
      { 
       locationList = FormatLocationForDB(locationList); 
      } 

      private void exit_Click(object sender, RoutedEventArgs e) 
      { 
       this.Close(); 
      } 
     } 

} 

Я пытался управлять progressbarvalue в потоке, но ничего не происходит вообще. Значение по-прежнему равно 0, когда программа завершена. Может кто-нибудь мне помочь? Есть ли легкая ошибка? Или я должен попробовать что-то еще, например, фонового работника (который выглядит примерно так же, как я думаю).

Спасибо за помощь

+0

Ты ничего (тяжелый) на нить не работает так, не устанавливая прогресс непосредственно проблемы. Вероятно, вы замораживаете свой графический интерфейс. Но если это проблема, спросите об этом. –

ответ

0
private double _progressLabelContent; 

public double ProgressLabelContent 
{ 
get {return _progressLabelContent; } 
set { _progressLabelContent=value; OnPropertyChanged("ProgressLabelContent"); } 
} 

public void updateProgressBar() 
{ 
    Application.Current.Dispatcher.Invoke(delegate 
    { 
     ProgressValue = ((double)progressCounter * 100)/locationList.Count; 
     ProgressLabelContent = ProgressValue + "/100"; 
    }); 

} 

Xaml

<Label Content={Binding Path=ProgressLabelContent} Foreground="White" TextBlock.TextAlignment="Center" Content="" HorizontalAlignment="Left" Margin="320,489,0,0" VerticalAlignment="Top" Width="100"/> 
Смежные вопросы