首先 - 请原谅我糟糕的发音。 我正在为excelsheet编写一个wpf验证器,虽然这个程序从谷歌获取信息,它应该显示进度条上的进度。我在网上看过很多关于多线程和后台工作的文章,但我认为没有什么能真正帮助我。
这是我的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"/>