使用DispatchingTimer每秒更新BindingList的问题

时间:2013-12-29 15:08:35

标签: c# wpf

我有一个带有ExpireTime的绑定列表,这是一个日期,然后我使用转换器将其转换为时间跨度,这样我就可以显示到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();
}

和我绑定的类

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

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

我的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>

我的转换器

    [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();
    }
}

解决方案 忘记将INotifyPropertyChanged添加到我的PlayerSearchResultTransfer

1 个答案:

答案 0 :(得分:2)

您正在ViewModel类上发起PropertyChanged事件。应该在PlayerSearchResultTransfer的每个实例上引发转换器以触发所有项目。

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

此外,请确保PlayerSearchResultTransfer类实现INotifyPropertyChanged以便在任何属性更改时刷新GUI。