0
votes

I've got a list of objects that I'm binding to a ListView and using a DataTemplate to show in a Xamarin app. So far, pretty simple. But the kicker is that I want one of the controls (a label specifically) to update continually.

So far this is what I have...

<ListView x:Name="ItemsListView"
          ItemsSource="{Binding Items}"
          VerticalOptions="FillAndExpand"
          HasUnevenRows="true"
          RefreshCommand="{Binding LoadItemsCommand}"
          IsPullToRefreshEnabled="true"
          IsRefreshing="{Binding IsBusy, Mode=OneWay}"
          CachingStrategy="RecycleElement"
          ItemSelected="OnItemSelected">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Padding="10">
                    <Label Text="{Binding Title}"
                           LineBreakMode="NoWrap"
                           Style="{DynamicResource ListItemTextStyle}"
                           FontSize="16" />
                    <mycountdown:TimerLabel Text="{Binding TimeRemainingString}"
                                            Style="{DynamicResource ListItemDetailTextStyle}"
                                            FontSize="13" />
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

And the code behind for my TimerLabel class...

public class TimerLabel : Label
{
    private bool beating;
    public TimerLabel()
    {
        StartHeartbeat();
    }

    public void StartHeartbeat()
    {
        //only start beating again if not currently beating.
        if (!beating)
        {
            beating = true;
            Heartbeat();
        }
    }

    public void StopHeartbeat()
    {
        beating = false;
    }

    async void Heartbeat()
    {
        while (beating)
        {
            this.Text = DateTime.UtcNow.ToLongTimeString();
        }
    }
}

This works, but the problem is that the heartbeat for each item in the list keeps running even when I navigate away from the page.

Ideally, the heartbeat would only run for items that are visible on screen, but I would settle for letting them all run and just disabling them when I leave the page.

The problem is I can't figure out how to access the StopHeartbeat() method from the page's code behind or the view model.

It's not going to be limited to only Labels either. I will end up having a few other controls that need to update in the UI thread continuously, but this is the simplest one to start with.

If there's another way I should be doing this, please say so.

Thanks!

2
PageDisappearing can be used when leave page. INotifyPropertyChanged can be used when model changed.Junior Jiang
are you trying to access it from your viewmodel?FreakyAli
Jason's comment worked perfectly. I was trying to figure out how to link to those events anyways since I used them in another part of my program, but I just couldn't figure out how to do it inside user controls.imdandman

2 Answers

0
votes

if you are Bind List in ListItem Source then please change it from List to ObservableCollection it will work let me know if any question or can you upload viewModel code as well

0
votes

Answered by the top comment in my post.