C# 使用DispatchingTimer每秒更新BindingList时出现问题

C# 使用DispatchingTimer每秒更新BindingList时出现问题,c#,wpf,C#,Wpf,我有一个带有ExpireTime的bindinglist,它是一个日期,然后我使用转换器将其转换为时间跨度,这样我就可以显示到ExpireTime的时间 private BindingList<PlayerSearchResultTransfer> _transferlistItems; public BindingList<PlayerSearchResultTransfer> TransferlistItems { get { return _transfer

我有一个带有ExpireTime的bindinglist,它是一个日期,然后我使用转换器将其转换为时间跨度,这样我就可以显示到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();
}
我的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();
    }
}
[ValueConversion(typeof(DateTime)、typeof(TimeSpan))]
公共类TimeRemainingConverter:IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、CultureInfo区域性)
{
var dateTime=(dateTime)值;
var timespan=dateTime-dateTime.Now;
返回时间跨度<新时间跨度(1000)
?新的时间跨度(0)
:新的时间跨度(时间跨度.小时,时间跨度.分钟,时间跨度.秒);
}
公共对象转换回(对象值、类型targetType、对象参数、CultureInfo区域性)
{
抛出新的NotImplementedException();
}
}
解决方案
忘记将INotifyPropertyChanged添加到我的PlayerSearchResultTransfer

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

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

另外,确保PlayerSearchResultTransfer类实现了INotifyPropertyChanged,允许GUI在任何属性更改时进行刷新。

这对于在每个对象上对其进行od很有意义,但它没有改变任何内容,仍然没有改变显示的时间范围。我在小样本中尝试过,但它对我有效。尝试在
ExpireTime
的getter上放置一个断点,看看它是否被命中。您正在使用绑定列表并使用转换器?是的,仅包含属性
ExpireTime
的simple
TestClass
的代码完全相同。您可以将该测试项目上载到何处吗?然后我可能会发现差异,看起来真的很奇怪
_uiTimer.Tick += (s, e) =>
{
    foreach (PlayerSearchResultTransfer player in TransferlistItems)
    {
        player.RaisePropertyChanged("ExpireTime");
    }
};