Reputation: 4
I'm developing a Windows Phone application. I have a ListBox, populated from a JSON file.
This JSON file, I get from a Web Server. When I sync my app with the server, the ListBox is not automatically populate (is empty). Need to exit the app and returns for the ListBox display the data.
So, I have not found a way for "refresh" my ListBox at runtime.
Sync button:
private void sinc(object sender, EventArgs e)
{
IsolatedStorageSettings iso = IsolatedStorageSettings.ApplicationSettings;
if (iso.TryGetValue<string>("isoServer", out retornaNome))
{
serv = retornaNome;
client = new WebClient();
url = serv + "/json.html";
Uri uri = new Uri(url, UriKind.RelativeOrAbsolute);
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_OpenReadCompleted);
client.DownloadProgressChanged += new DownloadProgressChangedEventHandler(client_DownloadProgressChanged);
client.OpenReadAsync(uri);
}
else
{
MessageBox.Show("Configure um servidor antes de sincronizar os dados!");
NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute));
}
}
Parse JSON:
try
{
using (var store = IsolatedStorageFile.GetUserStoreForApplication())
using (var readStream = new IsolatedStorageFileStream("json.html", FileMode.Open, FileAccess.Read, FileShare.Read, store))
using (var reader = new StreamReader(readStream))
{
text = reader.ReadToEnd();
}
{
DataContext = this;
// String JSON
string json = text;
// Parse JObject
JArray jObj = JArray.Parse(json);
Items = new ObservableCollection<Fields>(
jObj.Children().Select(jo => jo["result"]["fields"].ToObject<Fields>()));
}
}
catch (Exception)
{
MessageBox.Show("A lista de produtos será exibida somente após a sincronização dos dados!");
}
public ObservableCollection<Fields> Items { get; set; }
public class Fields
{
[JsonProperty(PropertyName = "FId")]
public int FId { get; set; }
public string FNome { get; set; }
public float FEstado1 { get; set; }
public string FPais { get; set; }
public string Quantity { get; set; }
public string lero { get; set; }
public string Quantity1 { get; set; }
public string FEstado { get; set; }
}
ListBox XAML:
<ListBox Name="List1" ItemsSource="{Binding Items}" Margin="0,85,0,0" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="242" />
<ColumnDefinition Width="128" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel Hold="holdListAdd" Margin="0,0,-62,17" Grid.ColumnSpan="3">
<StackPanel.Background>
<SolidColorBrush Color="#FF858585" Opacity="0.5"/>
</StackPanel.Background>
<TextBlock x:Name="NameTxt" Grid.Column="0" Text="{Binding FNome}" TextWrapping="Wrap" FontSize="40" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Grid.Column="1" Text="{Binding FEstado}" TextWrapping="Wrap" Margin="45,-6,12,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
<TextBlock Grid.Column="0" Text="R$" Margin="15,48,158,17" Style="{StaticResource PhoneTextSubtleStyle}"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Upvotes: 0
Views: 147
Reputation: 37780
Take a look at these two lines:
public ObservableCollection<Fields> Items { get; set; }
Items = new ObservableCollection<Fields>(
jObj.Children().Select(jo => jo["result"]["fields"].ToObject<Fields>()));
Since you're changing Items
property value, you should notify the view either this way:
public ObservableCollection<Fields> Items
{
get { return items; }
set
{
if (items != value)
{
items = value;
OnPropertyChanged("Items");
}
}
}
private ObservableCollection<Fields> items;
or this (if you don't want to change the property declaration):
Items = new ObservableCollection<Fields>(/* fill the collection */);
OnPropertyChanged("Items"); // this is enough for the view to re-read property value
Another way to do what you want, is not to change the property value, but to change it's content. This assumes, that Items
collection is already created, and you just call Clear
and then Add
for every result, which was loaded from the server:
public ObservableCollection<Fields> Items
{
get
{
return items ?? (items = new ObservableCollection<Fields>());
}
}
private ObservableCollection<Fields> items;
var newItems = jObj.Children().Select(jo => jo["result"]["fields"].ToObject<Fields>());
Items.Clear();
foreach (var item in newItems)
{
Items.Add(item);
}
Upvotes: 2