使用 WPF 应用程序将列表绑定到 Telerik RadGridView
Bind a List to Telerik RadGridView using WPF application
我正在从事一个从 Google 的 API 检索地址的项目。我收到来自 google 的回复,但我无法将地址结果 (AddressList) 显示到 radgridview。我正在使用 WPF 应用程序,只需要将结果显示到 RADGRIDVIEW。我正在使用 'ItemSource' 尝试绑定到网格,但出现以下错误:无效的跨线程访问。
代码
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>
听起来像是因为您正在尝试从 non-UI 线程更新绑定到 UI 的对象。为了使其正常工作,您需要要求调度员像这样为您进行更新。
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() =>
{
//Do something
}));
我个人使用具有 DispatcherHelper class 的 MVVM-Light 框架,因此我可以编写这样的代码
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//Do something
});
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)));
}
}
我正在从事一个从 Google 的 API 检索地址的项目。我收到来自 google 的回复,但我无法将地址结果 (AddressList) 显示到 radgridview。我正在使用 WPF 应用程序,只需要将结果显示到 RADGRIDVIEW。我正在使用 'ItemSource' 尝试绑定到网格,但出现以下错误:无效的跨线程访问。
代码
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>
听起来像是因为您正在尝试从 non-UI 线程更新绑定到 UI 的对象。为了使其正常工作,您需要要求调度员像这样为您进行更新。
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
new Action(() =>
{
//Do something
}));
我个人使用具有 DispatcherHelper class 的 MVVM-Light 框架,因此我可以编写这样的代码
DispatcherHelper.CheckBeginInvokeOnUI(() =>
{
//Do something
});
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)));
}
}