I am working on a project that retrieves addresses from Google's API. I am getting response from google, but I am having trouble displaying the address results(AddressList) to the radgridview. I am using a WPF application and just need to display the results to the RADGRIDVIEW. I am using 'ItemSource' to try to bind to the grid but I am getting the following error: Invalid Cross Thread Access.
CODE
public partial class AddressSearch : ContentAppEntityView
{
public AddressSearch()
{
InitializeComponent();
}
HttpWebRequest request = null;
#region **********SEARCHING**********
private void addressInput_GotFocus(object sender, RoutedEventArgs e)
{
if (addressInput.Text == "Search")
addressInput.Text = "";
else
addressInput.SelectAll();
}
private void addressInput_LostFocus(object sender, RoutedEventArgs e)
{
if (addressInput.Text == String.Empty)
{
addressInput.Text = "Search";
searchclose.Opacity = 0;
}
else if (addressInput.Text == "Search")
searchclose.Opacity = 0;
}
private void EmptySearch_Click(object sender, RoutedEventArgs e)
{
addressInput.Text = "Search";
searchclose.Opacity = 0;
}
private void addressInput_KeyDown(object sender, KeyEventArgs e)
{
searchclose.Opacity = 1;
}
private void Enter_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
var address = addressInput.Text;
var requestUri = string.Format("http://localhost/media/TextToSpeech/TextToSpeechService.svc/getDataProxy?url=https://maps.googleapis.com/maps/api/geocode/json?address={0}&key=AIzaSyCgsNpuUoH7m6U7lqeZjlLZ3MgM15PW15o", Uri.EscapeDataString(address));
//var requestUri = string.Format(ConfigurationManager.GetAppSetting("addressSearchGeoCode", Uri.EscapeDataString(address)));
HttpWebRequest request = WebRequest.Create(requestUri) as HttpWebRequest;
request.Method = "GET";
IAsyncResult result = request.BeginGetResponse(new AsyncCallback(RequestCompleted), request);
var dodo = result;
}
}
private void RequestCompleted(IAsyncResult result)
{
var request = (HttpWebRequest)result.AsyncState;
var response = (HttpWebResponse)request.EndGetResponse(result);
Stream stream = response.GetResponseStream();
try
{
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
Regex rgx = new Regex("<.*\\>");
string newResult = rgx.Replace(text, "");
JObject json = JObject.Parse(newResult);
JArray results = (JArray)json["results"];
List<double> latList = new List<double>();
List<double> lngList = new List<double>();
List<string> AddressList = new List<string>();
if (results.Count == 0)
{
MessageBox.Show("No results found");
}
else
{
foreach (JObject obj in results)
{
if (obj == null)
{
MessageBox.Show("Address returned no results");
}
string formattedAddress = (string)obj["formatted_address"];
AddressList.Add(formattedAddress);
double lat = (double)obj["geometry"]["location"]["lat"];
latList.Add(lat);
double lng = (double)obj["geometry"]["location"]["lng"];
lngList.Add(lng);
//TODO Add exception handling
}
this.addressGrid.ItemsSource = AddressList;
}
}
catch (Exception ex)
{
MessageBox.Show("Error" + ex.Message);
}
}
}
Section of XAML
<!--Address Results-->
<telerik:RadGridView Grid.Row="2" AutoGenerateColumns="True" x:Name="addressGrid" Margin="0 0 0 18"
ItemsSource="{Binding}" CanUserFreezeColumns="False" CanUserSelect="False"
EnableColumnVirtualization="True" EnableRowVirtualization="True" ShowGroupPanel="False" ScrollViewer.VerticalScrollBarVisibility="Visible"
CanUserDeleteRows="True" RowIndicatorVisibility="Collapsed" DataLoadMode="Asynchronous" HeaderRowStyle="{StaticResource ZoneActivityHeaderRowStyle}"
GroupPanelStyle="{StaticResource GroupPanelStyle}" Background="#00000000" VerticalGridLinesBrush="#00000000" HorizontalGridLinesBrush="#00000000" AlternationCount="2"
RowHeight="32" ShowColumnHeaders="False" RowStyle="{StaticResource ActivityRowStyle}" AlternateRowStyle="{StaticResource ActivityAlternateRowStyle}">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn Header="Targetting" Width="28" IsReadOnly="True" IsFilterable="False" ShowDistinctFilters="True" IsGroupable="False">
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<ctrl:TargetButton x:Name="targetButton" VerticalAlignment="Center" HorizontalAlignment="Center" />
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
<telerik:GridViewDataColumn Header="Address" Width="*" IsReadOnly="True"
IsFilterable="False" ShowDistinctFilters="True" IsGroupable="False">
<telerik:GridViewDataColumn.CellTemplate>
<DataTemplate>
<Grid>
<TextBlock Text="{Binding}" Foreground="White" FontFamily="Segoe UI"
FontSize="12" VerticalAlignment="Top" Margin="5" TextWrapping="Wrap" />
<Border Background="#00000000" Height="32" Margin="-5 0" />
</Grid>
</DataTemplate>
</telerik:GridViewDataColumn.CellTemplate>
</telerik:GridViewDataColumn>
</telerik:RadGridView.Columns>
</telerik:RadGridView>
<TextBlock Text="No addresses available" FontFamily="Segoe UI Semibold" FontSize="12" Foreground="#FFFFFF" Grid.Row="2" Margin="18" Visibility="{Binding AddressCollection.Count}" />
</Grid>
The RadGridView can only be accessed on the thread on which it was originally created. You could use the dispatcher to marshal any calls to the RadGridView back to the UI thread. Try this:
private void RequestCompleted(IAsyncResult result)
{
var request = (HttpWebRequest)result.AsyncState;
var response = (HttpWebResponse)request.EndGetResponse(result);
Stream stream = response.GetResponseStream();
try
{
StreamReader reader = new StreamReader(stream);
string text = reader.ReadToEnd();
Regex rgx = new Regex("<.*\\>");
string newResult = rgx.Replace(text, "");
JObject json = JObject.Parse(newResult);
JArray results = (JArray)json["results"];
List<double> latList = new List<double>();
List<double> lngList = new List<double>();
List<string> AddressList = new List<string>();
if (results.Count == 0)
{
Dispatcher.BeginInvoke(new Action(() => MessageBox.Show("No results found")));
}
else
{
foreach (JObject obj in results)
{
if (obj == null)
{
Dispatcher.Invoke(new Action(() => MessageBox.Show("Address returned no results")));
}
string formattedAddress = (string)obj["formatted_address"];
AddressList.Add(formattedAddress);
double lat = (double)obj["geometry"]["location"]["lat"];
latList.Add(lat);
double lng = (double)obj["geometry"]["location"]["lng"];
lngList.Add(lng);
//TODO Add exception handling
}
Dispatcher.Invoke(new Action(() => this.addressGrid.ItemsSource = AddressList));
}
}
catch (Exception ex)
{
Dispatcher.Invoke(new Action(() => MessageBox.Show("Error" + ex.Message)));
}
}
Sounds like it is because you are trying to update an object that is bound to the UI from a non-UI thread. In order for this to work you need to ask the dispatcher to do the update for you like this.
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() =>
{
//Do something
}));
Personally I use the MVVM-Light framework that has the DispatcherHelper class so I can write code like this
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//Do something
});
Related
I have a listview whose data is extracted from sqlite database, as shown below:
I want to check the user click the delete button, then the data on the list is deleted and the data in the sqlite database also deleted.
XAML:
<ListView x:Name="ListTryout" Grid.Row="1" Margin="0,5,0,10" ItemsSource="{Binding Source={StaticResource itemsViewSource}}" DataContext="{Binding SelectedItem, ElementName=itemListView}" IsItemClickEnabled="True" SelectionChanged="ListTryout_SelectionChanged" Background="{x:Null}" SelectionMode="Single">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Orientation="Vertical">
<TextBlock Margin="10,10,0,0" FontSize="20" Text="{Binding Judul}" Style="{StaticResource CaptionTextBlockStyle}" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<TextBlock Margin="10,10,0,0" FontSize="17" Text="{Binding JumlahSoal}" VerticalAlignment="Top" HorizontalAlignment="Left" FontWeight="SemiLight"/>
<TextBlock Margin="10,10,0,0" FontSize="17" Text="{Binding Durasi}" VerticalAlignment="Top" HorizontalAlignment="Left" FontWeight="SemiLight" Visibility="Collapsed"/>
<Line X1="0" X2="1" Stretch="Fill" Margin="10,10,10,0" Stroke="#FF4B4B4B"/>
</StackPanel>
<AppBarButton x:Name="deleteItemBtn" Grid.Column="1" Margin="0,0,50,0" Icon="Delete" HorizontalAlignment="Right" Click="deleteItemBtn_Click"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Code:
private void ReadTryoutList_Loaded(object sender, RoutedEventArgs e)
{
ReadAllDBName dbName = new ReadAllDBName();
DB_TryoutList = dbName.GetAllDBName();
ListTryout.ItemsSource = DB_TryoutList.OrderByDescending(i => i.ID).ToList();//Binding DB data to LISTBOX and Latest contact ID can Display first.
if(DB_TryoutList.Count == 0)
{
statuskosongStack.Visibility = Visibility.Visible;
ListTryout.Visibility = Visibility.Collapsed;
}
else
{
statuskosongStack.Visibility = Visibility.Collapsed;
ListTryout.Visibility = Visibility.Visible;
}
}
private void deleteItemBtn_Click(object sender, RoutedEventArgs e)
{
Db_Helper.DeleteQuiz(currentquiz.ID);
}
DatabaseHelper class:
public void CreateDatabase(string DB_PATH)
{
if (!CheckFileExists(DB_PATH).Result)
{
using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), DB_PATH))
{
conn.CreateTable<DBName>();
}
}
}
private async Task<bool> CheckFileExists(string fileName)
{
try
{
var store = await Windows.Storage.ApplicationData.Current.LocalFolder.GetFileAsync(fileName);
return true;
}
catch
{
return false;
}
}
// Insert the new history in the DBName table.
public void Insert(DBName dBName)
{
using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
{
conn.RunInTransaction(() =>
{
conn.Insert(dBName);
});
}
}
public DBName ReadName(int quizid)
{
using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
{
var existingName = conn.Query<DBName>("select * from DBName where ID =" + quizid).FirstOrDefault();
return existingName;
}
}
public ObservableCollection<DBName> ReadAllDBName()
{
try
{
using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
{
List<DBName> myCollection = conn.Table<DBName>().ToList<DBName>();
ObservableCollection<DBName> DBNameList = new ObservableCollection<DBName>(myCollection);
return DBNameList;
}
}
catch
{
return null;
}
}
public void DeleteQuiz(string ID)
{
using (SQLite.Net.SQLiteConnection conn = new SQLite.Net.SQLiteConnection(new SQLite.Net.Platform.WinRT.SQLitePlatformWinRT(), App.DB_PATH))
{
var existingquiz = conn.Query<DBName>("delete from DBName where ID ='" + ID + "'").FirstOrDefault();
if (existingquiz != null)
{
conn.RunInTransaction(() =>
{
conn.Delete(existingquiz);
});
}
}
}
I tried it, but the data can not be deleted on listview and also on the sqlite database.
How to handle it?
Set or bind the ItemsSource of the ListView to an ObservableCollection<T> and remove the item from this one, e.g.:
private ObservableCollecton<DBName> _source;
private void ReadTryoutList_Loaded(object sender, RoutedEventArgs e)
{
ReadAllDBName dbName = new ReadAllDBName();
DB_TryoutList = dbName.GetAllDBName();
_source = new ObservableCollecton<DBName>(DB_TryoutList.OrderByDescending(i => i.ID).ToList());
ListTryout.ItemsSource = _source;
if (DB_TryoutList.Count == 0)
{
statuskosongStack.Visibility = Visibility.Visible;
ListTryout.Visibility = Visibility.Collapsed;
}
else
{
statuskosongStack.Visibility = Visibility.Collapsed;
ListTryout.Visibility = Visibility.Visible;
}
}
private void deleteItemBtn_Click(object sender, RoutedEventArgs e)
{
var btn = sender as AppBarButton;
var item = btn.DataContext as DBName;
if (item != null)
{
_source.Remove(item);
Db_Helper.DeleteQuiz(currentquiz.ID);
}
}
I assume that GetAllDBName() are returning an IEnumerable<DBName> and that you are displaying DBNames in the ListView.
everyone
I am looking for a idea that helps me to solve my problem. I am trying to create a wpf programm which i could login on a webpage with given username and password in WPF, after that i could also get a successed message.
I have tried with following code:
Xaml file:
<StackPanel Orientation="Horizontal" Background="Black">
<TextBox x:Name="username" Width="200" Margin="2,2,10,2" Text="username"/>
<TextBox x:Name="password" Width="200" Margin="2,2,10,2" Text="password"/>
<Button Width="200" Content="Go!" Margin="2" Click="Button_Click" />
</StackPanel>
<StackPanel Orientation="Vertical" Grid.Row="1" >
<WebBrowser x:Name="wb1" Height="500" />
<TextBlock x:Name="state" Text="Connection" ></TextBlock>
</StackPanel>
Code Behinde:
...
public MainWindow()
{
InitializeComponent();
wb1.LoadCompleted += new LoadCompletedEventHandler(bws_LoadCompleted);
wb1.Navigated += new NavigatedEventHandler(bws_Navigated);
}
void bws_Navigated(object sender, NavigationEventArgs e)
{
HideScriptErrors(wb1, true);
}
void bws_LoadCompleted(object sender, NavigationEventArgs e)
{
switch (e.Uri.AbsolutePath)
{
case "/":
DoExample1();
break;
case "/login":
DoExample1();
break;
}
}
private void DoExample1()
{
TryFillInBing(username.Text, password.Text);
}
void TryFillInBing(string name, string passwd)
{
Thread.Sleep(500);
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() =>
{
if (!LoginInput(0, "username", "password", name, passwd) && Tries < 6)
{
Tries++;
TryFillInBing(name, passwd);
}
else
{
IHTMLFormElement form = GetForm(0);
form.submit();
}
}));
}
private bool UpdateTextInput(int formId, string name, string text)
{
bool successful = false;
IHTMLFormElement form = GetForm(formId);
if (form != null)
{
var element = form.item(name: name);
if (element != null)
{
var textinput = element as HTMLInputElement;
textinput.value = text;
successful = true;
}
}
return successful;
}
private bool LoginInput(int formId, string name, string passwd, string text, string pw)
{
bool successful = false;
IHTMLFormElement form = GetForm(formId);
if (form != null)
{
var element = form.item(name);
var pass = form.item(passwd);
if (element != null && pass != null)
{
var textinput = element as HTMLInputElement;
textinput.value = text;
var passinput = pass as HTMLInputElement;
passinput.value = pw;
successful = true;
}
}
return successful;
}
...
...
...
private void Button_Click(object sender, RoutedEventArgs e)
{
string conquerclubLogin = "https://www.conquerclub.com";
string googleWeb = "http://www.google.de";
wb1.Navigate(conquerclubLogin);
}
But it showed me the same login page and i did not receive any message for successfull login...Has anyone an idea for me?
Cheers, Carvin
I have a textbox to do a search using textbox_textchanging and a listview. When the user typed the letter o, it will show the search result of the letter o on listview and when user typed the word omapukis, it will show the search result from The word omapukis.
XAML:
<TextBox
x:Name="searchBox"
Grid.Row="0"
Margin="10,0,10,10"
Text=""
Foreground="Black"
Background="#E6FDFDFD"
BorderBrush="#FF7A7A7A"
PlaceholderText="Search in Indonesia Products & Bussiness"
FontFamily="Segoe UI Black"
FontSize="16"
TextChanging="searchBox_TextChanging" />
<ListView
x:Name="suggestionList"
Grid.RowSpan="2"
Grid.Column="1"
Margin="67,75,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="1135" Height="400"
Background="White"
BorderBrush="Black"
BorderThickness="1"
Visibility="Collapsed"
AutomationProperties.AutomationId="ItemsListView"
AutomationProperties.Name="Items"
ItemsSource="{Binding Source={StaticResource itemsViewSource}}"
IsItemClickEnabled="True"
ItemClick="suggestionList_ItemClick">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<TextBlock
x:Name="Nama"
Text="{Binding Title}"
Style="{StaticResource TitleTextBlockStyle}"
TextWrapping="NoWrap"
Visibility="Visible"
Foreground="Black"
HorizontalAlignment="Left"
Margin="10,0,10,10"
SelectionHighlightColor="#FFBFA342"
FontSize="16"/>
<TextBlock
Text="{Binding ID}"
Style="{StaticResource CaptionTextBlockStyle}"
TextWrapping="NoWrap"
Visibility="Collapsed"
Foreground="#FFAAAAAA"/>
</StackPanel>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.ItemContainerStyle>
<Style TargetType="FrameworkElement">
<Setter Property="Margin" Value="0,0,0,5"/>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Code:
ObservableCollection<SearchClass> suggestionDatasourceDetail = new ObservableCollection<SearchClass>();
ObservableCollection<SearchClass> historyDatasourceDetail = new ObservableCollection<SearchClass>();
private async void searchBox_TextChanging(TextBox sender, TextBoxTextChangingEventArgs args)
{
string keyword = searchBox.Text;
suggestionList.ItemsSource = null;
suggestionList.Items.Clear();
suggestionDatasourceDetail.Clear();
koneksiErrorStack.Visibility = Visibility.Collapsed;
requestErrorStack.Visibility = Visibility.Collapsed;
ConnectionProfile connections = NetworkInformation.GetInternetConnectionProfile();
if (connections != null && connections.GetNetworkConnectivityLevel() == NetworkConnectivityLevel.InternetAccess)
{
itemGridView.Visibility = Visibility.Visible;
busyIndicator.IsActive = true;
try
{
string urlPath = "http://.../suggest.json?q=" + keyword + "&module=listings&page=1&token=3f63-dc43-c8d5-eb45-8cbf-b72d-9d98-800f";
var httpClient = new HttpClient(new HttpClientHandler());
var values = new List<KeyValuePair<string, string>>{};
HttpResponseMessage response = await httpClient.GetAsync(urlPath);
response.EnsureSuccessStatusCode();
if (!response.IsSuccessStatusCode)
{
busyIndicator.IsActive = false;
RequestException();
}
string jsonText = await response.Content.ReadAsStringAsync();
JsonObject jsonObject = JsonObject.Parse(jsonText);
JsonArray jsonData = jsonObject["data"].GetArray();
foreach (JsonValue groupValue1 in jsonData)
{
JsonObject groupObject2 = groupValue1.GetObject();
double id = groupObject2["id"].GetNumber();
string title = groupObject2["title"].GetString();
string type = groupObject2.ContainsKey("type") && groupObject2["type"] != null ? groupObject2["type"].GetString() : string.Empty;
SearchClass file1 = new SearchClass();
file1.ID = Convert.ToInt32(id);
file1.Title = title;
if (type != string.Empty)
{
file1.Type = type;
}
if (file1.Type != "blog")
{
suggestionDatasourceDetail.Add(file1);
}
}
suggestionList.ItemsSource = searchDatasourceDetail;
if (suggestionDatasourceDetail.Count == 0)
{
busyIndicator.IsActive = false;
loading.Visibility = Visibility.Collapsed;
suggestionList.Visibility = Visibility.Collapsed;
}
else
{
busyIndicator.IsActive = false;
loading.Visibility = Visibility.Collapsed;
suggestionList.Visibility = Visibility.Visible;
}
}
catch (HttpRequestException ex)
{
busyIndicator.IsActive = false;
loading.Visibility = Visibility.Collapsed;
RequestException();
suggestionList.Visibility = Visibility.Collapsed;
}
}
else
{
busyIndicator.IsActive = false;
loading.Visibility = Visibility.Collapsed;
ConnectionException();
suggestionList.Visibility = Visibility.Collapsed;
}
}
I have a problem, when typing the letter o, it will show the search result of the letter o on listview, while when user type omapukis, then Will display the search results will show from o, om, oma, oma, omapukis. I want to display search results from the word omapukis only (search results with the last letter or word only).
And after that I search for the word kalingga, then the search results will appear from om, oma, oma, omapukis, ka, kali, kalingga. I want to display search results from the word kalingga only (search results with the last letter or word only).
How to resolve it in order to display search results in listview of only the last letter or word entered by the user?
You should be using AutoSuggestBox : https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.autosuggestbox and use TaskCancellation for previous search. Basically have a logic to cancel the previous search in case user has modified anything on the AutoSuggestBox. Something like this..
private CancellationTokenSource CTS = new CancellationTokenSource();
public async Task StartSearch(string query)
{
this.CTS.Cancel(true);
this.CTS = new CancellationTokenSource();
try
{
await Task.Run(() =>
{
try
{
if (this.CTS.IsCancellationRequested)
{
return;
}
// Your actual searching logic... If you decide to update the UI here then make sure this runs on UI Thread.
if (this.CTS.IsCancellationRequested)
{
return;
}
}
catch (Exception ex)
{
// Logger...
}
}, this.CTS.Token);
}
catch (TaskCanceledException taskCnclErr)
{
// You can ignore this error
}
catch (Exception ex)
{
//Logger...
throw;
}
finally
{
}
}
Now, hook the StartSearch() method to the event trigger from AutoSuggestBox
TextChanged or QuerySubmitted
You can wait for a little while before searching your data. Try adding this snippet at the beginnig of the TextChanging method (add _lockable as private field of type object):
lock (_lockable)
{
var term = searchBox.Text;
await Task.Delay(250);
if (term != searchBox.Text)
return;
}
This will wait a quarter of a second after the user entered the text before starting the search. If the term changed, it would only search the new term. Try experimenting with the delay time to find the optimal time for your scenario.
I have a listbox like this:
<toolkit:ListPicker Name="lstBoxBaseUnitOfMeasure" Width="100" Margin="0,4,0,0">
<toolkit:ListPicker.Items>
<TextBlock Text="EACH" Height="30"/>
<TextBlock Text="GRAM" Height="30"/>
</toolkit:ListPicker.Items>
</toolkit:ListPicker>
I would like to send selected item to Local Database like this:
private void AddProduct_Click(object sender, RoutedEventArgs e)
{
TblProductsToOrder newProductToOrder = new TblProductsToOrder
{
OrderNId = selectedID,
Quantity = int.Parse(txtQuantity.Text),
**BaseUnitOfMeasure = ??????????????**
};
}
ListPicker fires an event,SelectionChanged whenever a item is selected. You will need to listen to that event
<toolkit:ListPicker Name="lstBoxBaseUnitOfMeasure" Width="100" Margin="0,4,0,0" SelectionChanged="listPicker_SelectionChanged">
<toolkit:ListPicker.Items>
<TextBlock Text="EACH" Height="30"/>
<TextBlock Text="GRAM" Height="30"/>
</toolkit:ListPicker.Items>
</toolkit:ListPicker>
private void listPicker_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (lstBoxBaseUnitOfMeasure.SelectedItem != null)
{
var texBlock = (TextBlock) lstBoxBaseUnitOfMeasure.SelectedItem;
selectedUnit = texBlock.Text;
TblProductsToOrder newProductToOrder = new TblProductsToOrder
{
OrderNId = selectedID,
Quantity = int.Parse(txtQuantity.Text),
BaseUnitOfMeasure = selectedUnit
};
}
}
Assuming that BaseUnitOfMeasure property is of type String, you can try this way :
String selectedUnit = "";
if(lstBoxBaseUnitOfMeasure.SelectedItem != null)
{
var selectedTextBlock = (TextBlock)lstBoxBaseUnitOfMeasure.SelectedItem;
selectedUnit = selectedTextBlock.Text;
}
TblProductsToOrder newProductToOrder = new TblProductsToOrder
{
OrderNId = selectedID,
Quantity = int.Parse(txtQuantity.Text),
BaseUnitOfMeasure = selectedUnit
};
First of all - please excuse my poor pronunciation.
I'm programming a wpf-validator for a excelsheet and while this programm is getting Infos from google it should show the progress on a progressbar. I've read a lot of articles in the web about multithreading and backgroundworking but I think nothing can really help me.
Here is my 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>
And here is my 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();
}
}
}
I tried to manage the progressbarvalue in the thread but nothing happens at all. The value is still 0 when the programm is finished. Could someone help me? Is there an easy mistake? Or should i try somethink else like the backgroundworker (which looks pretty the same i think).
Thanks for help
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"/>