Mech0z
Mech0z

Reputation: 3647

Issues updating BindingList every second with DispatchingTimer

I have a bindinglist with an ExpireTime which is a date, I then use a converter to convert it to a timespan so I can show how long until ExpireTime

private BindingList<PlayerSearchResultTransfer> _transferlistItems;
public BindingList<PlayerSearchResultTransfer> TransferlistItems
{
    get { return _transferlistItems; }
    set { _transferlistItems = value; RaisePropertyChanged(() => TransferlistItems);}
}

private readonly DispatcherTimer _uiTimer;

public TransferListViewModel(IPlayerSearchQuery playerSearchQuery)
{
    _uiTimer = new DispatcherTimer();
    _uiTimer.Tick += (s, e) => RaisePropertyChanged("ExpireTime");
    _uiTimer.Interval = new TimeSpan(0,0,1);
    _uiTimer.Start();
}

and the class I am binding against

public class PlayerSearchResultTransfer : PlayerSearchResult
{
    private DateTime _expireTime;
    public event PropertyChangedEventHandler PropertyChanged;

    public DateTime ExpireTime
    {
        get { return _expireTime; }
        set
        {
            _expireTime = value;
            RaisePropertyChanged("ExpireTime");
        }
    }

My WPF

    <UserControl.Resources>
        <converters:TimeRemainingConverter x:Key="TimeRemainingConverter" />
    </UserControl.Resources>

    <Grid>

        <DataGrid ItemsSource="{Binding TransferlistItems}"
                  AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="First Name" IsReadOnly="True">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding FirstName}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Last Name" IsReadOnly="True">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding LastName}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Expires" IsReadOnly="True">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding ExpireTime, Converter={StaticResource TimeRemainingConverter}}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Bid" IsReadOnly="True">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding BidValue}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn Header="Buyout" IsReadOnly="True">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding BuyoutValue}" />
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</UserControl>

And my converter

    [ValueConversion(typeof(DateTime), typeof(TimeSpan))]    
public class TimeRemainingConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var dateTime = (DateTime)value;
        var timespan = dateTime - DateTime.Now;

        return timespan < new TimeSpan(1000)
            ? new TimeSpan(0)
            : new TimeSpan(timespan.Hours, timespan.Minutes, timespan.Seconds);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Solution Had forgot to add INotifyPropertyChanged to my PlayerSearchResultTransfer

Upvotes: 1

Views: 84

Answers (1)

Rohit Vats
Rohit Vats

Reputation: 81253

You are raising PropertyChanged event on ViewModel class. It should be raised on every instance of PlayerSearchResultTransfer for converter to fire for all items.

_uiTimer.Tick += (s, e) =>
{
    foreach (PlayerSearchResultTransfer player in TransferlistItems)
    {
        player.RaisePropertyChanged("ExpireTime");
    }
};

Also, make sure PlayerSearchResultTransfer class implements INotifyPropertyChanged to let GUI refresh on any property change.

Upvotes: 2

Related Questions