Question

i have a custom control - Contact Card:

<Grid>
    <Grid.Background>
        <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
            <GradientStop Color="#FFD8B8EA"/>
            <GradientStop Color="White" Offset="1"/>
        </LinearGradientBrush>
    </Grid.Background>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Image Source="images.jpg" />
    <StackPanel Grid.Column="1">
        <TextBlock Text="{Binding Path=name}" Foreground="Black" FontSize="20" />
        <TextBlock Text="{Binding Path=surname}" Foreground="Black" FontSize="20" />
    </StackPanel>
</Grid>

And a container that will hold 4 Cards (also a custom user control):

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <StackPanel x:Name="FirstItem" Grid.Column="0" Grid.Row="0"/>
    <StackPanel x:Name="SecondItem" Grid.Column="0" Grid.Row="1"/>
    <StackPanel x:Name="ThirdItem" Grid.Column="1" Grid.Row="0"/>
    <StackPanel x:Name="FourthItem" Grid.Column="1" Grid.Row="1"/>
</Grid>

And here is my object class:

class FullObject
{
    public string UpdateTime { get; set; }
    public List<Contact> contacts { get; set; }
    public List<Region> regions { get; set; }
}

The problem i have is with List

FullObject data is coming from service in JSON format, so i do:

FullObjectt = JsonConvert.DeserializeObject<FullObject>(result);

And populate my FlipView with cards like so:

FourItems FI = new FourItems();
        for (int i = 0; i < 4; i++)
        {
            ContactCard CC = new ContactCard();
            CC.DataContext = FullObjects.contacts[i];
            if (i == 0)
            {
                FI.FirstItem.Children.Add(CC);
            }
            else if (i == 1)
            {
                FI.SecondItem.Children.Add(CC);
            }
            else if (i == 2)
            {
                FI.ThirdItem.Children.Add(CC);
            }
            else
            {
                FI.FourthItem.Children.Add(CC);
                FlipView.Items.Add(FI);
            }
        }

It looks like this:

enter image description here

When i get notified, that some contact data has changed i get from server a List with only changed Contacts. So i will find the changed contact in my currently loaded FullObject and replace it with new one:

Lets take for example that first contact name has changed

I will do this:

Contact new = JsonConvert.DeserializeObject<Contact>(result);
FullObjectt.contacts[0]=new;

But my card data doesn't change until i reset the Data Context. Is there a way but to make ContactCard update data when i did this?:

Contact new = JsonConvert.DeserializeObject<Contact>(result);
FullObjectt.contacts[0]=new;

I have tried to change List to ObservableCollection, but failed, could anybody guide me?

EDIT:

I have changed my List in FullObject class to ObservableCollection:

class FullObject : INotifyCollectionChanged 
{
    public string spTimestamp { get; set; }
    public ObservableCollection<Contact> contacts { get; set; }
    public string scTimestamp { get; set; }
    public List<Region> regions { get; set; }

}

And on button click i do (just to test):

private void Button_Click(object sender, RoutedEventArgs e)
    {
        FullObjects.contacts[0] = new Contact();
    }

And it doesn't update the Card...

Was it helpful?

Solution

Problem is in the way you are creating FourItems view. Here in this line -

ContactCard CC = new ContactCard();
CC.DataContext = FullObjects.contacts[i];
if (i == 0)
{
   FI.FirstItem.Children.Add(CC);
}

you are setting DataContext explicitly for ContactCard and later on changed it completely to new reference which obviously won't get reflect on UI unless you manually reset DataContext.

Instead you should have an ItemsControl and bind its ItemsSource directly to Contacts ObservableCollection. You can define ItemTemplate of itemsControl to represent one ContactCard. This way you will get CollectionChanged notification of observable collection and UI will gets update automatically.

View to hold four controls (Get rid of stackpanels) -

<Grid>
   <ItemsControl x:Name="ContactItems">
       <ItemsControl.ItemsPanel>
          <ItemsPanelTemplate>
              <UniformGrid Columns="2"/>
          </ItemsPanelTemplate>
       </ItemsControl.ItemsPanel>
       <ItemsControl.ItemTemplate>
           <DataTemplate>
               <local:ContactCard/> <-- Declare local namespace in XAML where 
                                        ContactCard control is declared.
           </DataTemplate>
       </ItemsControl.ItemTemplate>
   </ItemsControl>
</Grid>

And populate code should be like this -

FourItems FI = new FourItems();
FI.ContactItems.ItemsSource = FullObjects.contacts;
FlipView.Items.Add(FI);

Now any update in collection contacts will be listen by ItemsControl since its binded to it and your UI will update accordingly. Make sure contacts is ObservableCollection.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top