Rene Sá
Rene Sá

Reputation: 4

How refresh a ListBox at runtime?

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

Answers (1)

Dennis
Dennis

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

Related Questions