2017-01-30 64 views
0

我正在研究從Google API檢索地址的項目。我得到了谷歌的迴應,但我無法將地址結果(AddressList)顯示到radgridview。我正在使用WPF應用程序,只需要將結果顯示給RADGRIDVIEW。我正在使用'ItemSource'嘗試綁定到網格,但我收到以下錯誤:無效的跨線程訪問。使用WPF應用程序將列表綁定到Telerik RadGridView

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); 
     } 

    } 

} 

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> 

回答

1

的RadGridView只能在它最初創建的線程可以訪問編寫代碼。您可以使用調度程序將任何對RadGridView的調用封送回UI線程。試試這個:

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))); 
    } 
} 
+0

調度員正是我需要使用的。這工作完美。 – developerME

1

第聽起來那是因爲你要更新綁定到UI從非UI線程的對象。爲了這個工作,你需要讓調度員爲你做這個更新。

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, 
        new Action(() => 
        { 
         //Do something 
        })); 

我個人使用的MVVM光強的框架,具有DispatcherHelper類,所以我可以這樣

    DispatcherHelper.CheckBeginInvokeOnUI(() => 
        { 
         //Do something 
        }); 
+0

我本來可以走這條路,它可以正常工作。但對於我的程序,我決定使用@ mm8。但是,謝謝你的回答!它可能在未來派上用場。 – developerME