在datagrid中只刷新一个单元格

时间:2014-05-10 20:16:04

标签: c# wpf xaml datagrid

我有实现了TrulyObservableCollection的数据网格(Notify ObservableCollection when Item changes) - 我需要被告知在线是否有编辑,因为我将我的数据网格保存到sqlite(使用sqlite-net)。

该可观察集合包含类型的项目让我们说" plane"并且每个平面都有属性 lastContact (其中存储了最后一次联系的时间),我必须实时显示上次联系的经过时间。

我做了类似的事情:

MODELVIEW:

...
public TrulyObservableCollection<Plane> PlanesCollection { get; set; }
...

view(初始化dateconverter,无需在此处写)

<DataGrid ItemsSource="{Binding PlanesCollection}">    
    <DataGrid.Columns>
        <DataGridTextColumn Header="Call Signal" Binding="{Binding Path=CallSign}" Width="auto" />
        <DataGridTextColumn Header="Type" Binding="{Binding Path=Type}" Width="auto" />

        <DataGridTemplateColumn IsReadOnly="True" Header="Last Contact" Width="Auto">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*" />
                            <ColumnDefinition Width="*" />
                        </Grid.ColumnDefinitions>

                        <TextBlock HorizontalAlignment="Stretch" TextAlignment="Center" Grid.Column="0" Text="{Binding Path=LastContact, StringFormat=\{0:HH:mm\}}" />
                        <TextBlock HorizontalAlignment="Stretch" TextAlignment="Center" Grid.Column="1" Text="{Binding Path=LastContact, Converter={StaticResource dateConverter}}" />
                    </Grid>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>    
</Datagrid> 

和转换器仅显示上次联系后经过的时间。

我的问题是,我不知道如何更新(必须至少每分钟更新一次)单元格,而不用刷新整个数据网格这是不好的解决方案,因为当用户在行和数据网格中输入内容时刷新所有输入单元格的东西都丢失了......

所以我的问题是如何正确地做到(或者我的整个概念是不是很糟糕?) 感谢

1 个答案:

答案 0 :(得分:1)

一个解决方案可能是MultiBinding - 第一个属性是现有的LastContact,第二个属性是视图模型上的新属性,称为“CurrentTime”或其他属性。运行一个定时器,每隔X秒更新一次CurrentTime属性,这应该触发绑定更新。

这样的事情:

<TextBlock>
    <TextBlock.Text>
        <MultiBinding Converter="{StaticResource multiDateConverter}">
            <Binding Path="LastContact" />
            <Binding Path="DataContext.CurrentTime" 
                     RelativeSource="{RelativeSource AncestorType=DataGrid}" />
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

在这里,您需要将日期转换器更改为IMultiValueConverter。举个例子:

public class MultiDateConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (!(values.First() is DateTime))
            return DependencyProperty.UnsetValue;
        return string.Format("{0:N1} seconds ago", DateTime.Now.Subtract((DateTime)values.First()).TotalSeconds);
    }

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

最后一部分只是运行一个调度程序计时器来更新新的“CurrentTime”属性:

const int refreshRateInSeconds = 1;
var timer = new DispatcherTimer();
timer.Tick += (sender, args) => CurrentTime = DateTime.Now;
timer.Interval = TimeSpan.FromSeconds(refreshRateInSeconds);
timer.Start();