c# – WPF DataBinding当我使用Convert来格式化日期时非常慢

c# – WPF DataBinding当我使用Convert来格式化日期时非常慢,第1张

概述我正在编写一个简单的应用程序来显示DataGrid上的一些数据.数据只是一个度量(浮点数)和一个时间戳.时间戳是一个uint,自2000年以来以秒为单位. 我成功地完成了任务,但确实注意到显示数据网格需要很长时间(约1分钟).大约有20,000个数据.我不认为20,000个由uint和float组成的数据就是那么简单.下一个请求是将时间显示为格式化时间而不是自2000年以来的秒数.这是通过使XAM 我正在编写一个简单的应用程序来显示DataGrID上的一些数据.数据只是一个度量(浮点数)和一个时间戳.时间戳是一个uint,自2000年以来以秒为单位.

我成功地完成了任务,但确实注意到显示数据网格需要很长时间(约1分钟).大约有20,000个数据.我不认为20,000个由uint和float组成的数据就是那么简单.下一个请求是将时间显示为格式化时间而不是自2000年以来的秒数.这是通过使XAML看起来像这样:

<kit:DataGrIDTextColumn header="FilteredValue" Binding="{Binding Path=FilteredValue}" /><kit:DataGrIDTextColumn header="Timestamp" Binding="{Binding Path=Timestamp,Converter={StaticResource TimeConverter}}" CanUserSort="False" />

TimeConverter方法如下所示:

public object Convert(object value,Type targettype,object parameter,System.Globalization.CultureInfo culture){    DateTime currentDateTime = new DateTime(2000,1,DateTimeKind.Utc);    currentDateTime = currentDateTime.AddSeconds((uint)value);    return currentDateTime.ToString();                  }

这也很好.但是,事实证明一些原始数据可以是0xFFFFFFFF.@H_301_22@这意味着没有数据或无效数据.在这种情况下,我不想转换为日期.所以我写道:

public object Convert(object value,System.Globalization.CultureInfo culture){    if ((uint)value == 0xFFFFFFFF)    {    // don't bother to convert    return ((uint)value).ToString("X");    }   else   {    DateTime currentDateTime = new DateTime(2000,DateTimeKind.Utc);    currentDateTime = currentDateTime.AddSeconds((uint)value);    return currentDateTime.ToString();   }}

它再次起作用,但速度很慢.比原来慢,大约需要10分钟.我很惊讶这一点.这是多少代码运行23,000次的情况吗?@H_301_22@1.我该怎么办?我可以在XAML中执行某些 *** 作,以便在没有必要时调用我的Converter吗?@H_301_22@2.当我有一个测量值(FilteredValues)的0xFFFFFFFF时,它显示为NaN.这可能没问题,但只显示0xFFFFFFFF或“无数据”会很好.我认为它已设置为NaN,因为底层数据类型是浮点数.

有任何想法吗?

谢谢,@H_301_22@戴夫

这是XAML.最后一个DatagrID是感兴趣的.请注意,我甚至将“IsVirtualizing”设置为True.还要注意使用ScrollVIEwer.我这样做是因为否则我无法看到最后一个网格上的所有行(最终显示).删除它并没有加快速度.

<Window x:Class="STDatabaseReader.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:chartingToolkit="clr-namespace:System.windows.Controls.DataVisualization.Charting;assembly=System.windows.Controls.DataVisualization.Toolkit" xmlns:kit="http://schemas.microsoft.com/wpf/2008/toolkit" xmlns:local="clr-namespace:STDatabaseReader"    title="Smart Transmitter Database Reader"><Window.Resources>    <local:BytesToStringConverter x:Key="BytesToStringConverter"></local:BytesToStringConverter>    <local:TimeConverter x:Key="TimeConverter"></local:TimeConverter></Window.Resources><GrID>     <ScrollVIEwer>            <StackPanel OrIEntation="Vertical">            <button name="m_btnFetchData" HorizontalAlignment="left" Click="m_btnFetchData_Click">Fetch file</button>            <StackPanel OrIEntation="Horizontal">                <StackPanel OrIEntation="Vertical">                    <Label HorizontalAlignment="Center">Partition 1</Label>                    <kit:DataGrID name="m_grIDPartion1" autoGenerateColumns="False">                        <kit:DataGrID.Columns>                            <kit:DataGrIDTextColumn header="header Info" Binding="{Binding Path=headerInfo,Converter={StaticResource BytesToStringConverter}}" CanUserSort="False" />                            <kit:DataGrIDTextColumn header="Transmitter ID" Binding="{Binding Path=TransmitterID,Converter={StaticResource BytesToStringConverter}}" CanUserSort="False" />                            <kit:DataGrIDTextColumn header="DeviceNumber" Binding="{Binding Path=DeviceNumber}" />                            <kit:DataGrIDTextColumn header="HarDWareversion" Binding="{Binding Path=HarDWareversion}" />                            <kit:DataGrIDTextColumn header="CRC" Binding="{Binding Path=CRC}" />                        </kit:DataGrID.Columns>                    </kit:DataGrID>                </StackPanel>                <StackPanel OrIEntation="Vertical">                    <Label HorizontalAlignment="Center">Partition 3</Label>                    <kit:DataGrID name="m_grIDPartion3" autoGenerateColumns="False">                        <kit:DataGrID.Columns>                            <kit:DataGrIDTextColumn header="header Info" Binding="{Binding Path=headerInfo,Converter={StaticResource BytesToStringConverter}}" CanUserSort="False" />                            <kit:DataGrIDTextColumn header="SystemTime" Binding="{Binding Path=SystemTime,Converter={StaticResource TimeConverter}}" />                        </kit:DataGrID.Columns>                    </kit:DataGrID>                </StackPanel>            </StackPanel>            <StackPanel OrIEntation="Vertical">                <Label HorizontalAlignment="Center">Partition 2</Label>                <kit:DataGrID name="m_grIDPartion2" autoGenerateColumns="False">                    <kit:DataGrID.Columns>                        <kit:DataGrIDTextColumn header="header Info" Binding="{Binding Path=headerInfo,Converter={StaticResource BytesToStringConverter}}" CanUserSort="False" />                        <kit:DataGrIDTextColumn header="FirmwareRevision" Binding="{Binding Path=FirmwareRevision,Converter={StaticResource BytesToStringConverter}}" CanUserSort="False" />                        <kit:DataGrIDTextColumn header="SoftwarePartNumber" Binding="{Binding Path=SoftwarePartNumber,Converter={StaticResource BytesToStringConverter}}" CanUserSort="False" />                        <kit:DataGrIDTextColumn header="FirmwareUpgradeTime" Binding="{Binding Path=FirmwareUpgradeTime,Converter={StaticResource TimeConverter}}" />                        <kit:DataGrIDTextColumn header="DatabaseEraseTime" Binding="{Binding Path=DatabaseEraseTime,Converter={StaticResource TimeConverter}}" />                        <kit:DataGrIDTextColumn header="RangeEnzymeElectrode" Binding="{Binding Path=RangeEnzymeElectrode}" />                        <kit:DataGrIDTextColumn header="OffsetEnzymeElectrode" Binding="{Binding Path=OffsetEnzymeElectrode}" />                        <kit:DataGrIDTextColumn header="BiasValue" Binding="{Binding Path=BiasValue}" />                    </kit:DataGrID.Columns>                </kit:DataGrID>            </StackPanel>            <StackPanel OrIEntation="Horizontal">                <StackPanel OrIEntation="Vertical">                    <Label HorizontalAlignment="Center">Partition 4 - headerInfo</Label>                    <kit:DataGrID name="m_grIDDataheader" autoGenerateColumns="False">                        <kit:DataGrID.Columns>                            <kit:DataGrIDTextColumn header="header Info" Binding="{Binding Path=headerInfo,Converter={StaticResource BytesToStringConverter}}" CanUserSort="False" />                        </kit:DataGrID.Columns>                    </kit:DataGrID>                </StackPanel>                <StackPanel   OrIEntation="Vertical">                    <Label HorizontalAlignment="Center">Partition 4 - Chemistry Data</Label>                        <kit:DataGrID name="m_grIDData" autoGenerateColumns="False" VirtualizingStackPanel.IsVirtualizing="True"  Loaded="m_grIDData_Loaded">                            <kit:DataGrID.Columns>                                <!--                                <kit:DataGrIDTextColumn header="Noise" Binding="{Binding Path=Noise,StringFormat=\{0:X8\}}" />                                <kit:DataGrIDTextColumn header="FilteredValue" Binding="{Binding Path=FilteredValue,StringFormat='X'}" />                                 <kit:DataGrIDTextColumn header="Timestamp" Binding="{Binding Path=Timestamp,StringFormat=\{0:X\}}" />   -->                            <kit:DataGrIDTextColumn header="Noise" Binding="{Binding Path=Noise}" />                            <kit:DataGrIDTextColumn header="FilteredValue" Binding="{Binding Path=FilteredValue}" />                            <kit:DataGrIDTextColumn header="Timestamp" Binding="{Binding Path=Timestamp,Converter={StaticResource TimeConverter}}" CanUserSort="False" />                        </kit:DataGrID.Columns>                        </kit:DataGrID>                </StackPanel >            </StackPanel>        </StackPanel>     </ScrollVIEwer>     </GrID>
解决方法 由于该列是DataGrIDTextColumn,您可以通过在转换器中返回它来显示0xFFFFFFFF

if ((uint)value == 0xFFFFFFFF){    // don't bother to convert    return "0xFFFFFFFF";}

至于DataGrID很慢,它应该默认使用VirtualizingStackPanel,所以如果你没有改变它,那么它应该非常快,因为你只会使用目前对用户可见的DataGrIDRows.此外,转换器中的代码几乎没有时间.

因此,你的DataGrID变慢的最可能的原因可能是你已经将ItemsPanel更改为VirtualizingStackPanel以外的其他东西,或者以某种方式禁用了虚拟化,但是如果没有看到你的DataGrID是如何定义的话很难说清楚

编辑@H_301_22@在DataGrID完成加载后运行以下代码,例如在DataGrID的Loaded事件中.如果MessageBox显示一个大数字(不应超过50),那么您就有问题的根源.

private voID DataGrID_Loaded(object sender,RoutedEventArgs e){    DataGrID dataGrID = sender as DataGrID;    List<DataGrIDRow> generatedDataGrIDRows = VisualTreeHelpers.GetVisualChildCollection<DataGrIDRow>(dataGrID);    MessageBox.Show(generatedDataGrIDRows.Count.ToString());}public static List<T> GetVisualChildCollection<T>(object parent) where T : Visual{    List<T> visualCollection = new List<T>();    GetVisualChildCollection(parent as DependencyObject,visualCollection);    return visualCollection;}private static voID GetVisualChildCollection<T>(DependencyObject parent,List<T> visualCollection) where T : Visual{    int count = VisualTreeHelper.GetChildrenCount(parent);    for (int i = 0; i < count; i++)    {        DependencyObject child = VisualTreeHelper.GetChild(parent,i);        if (child is T)        {            visualCollection.Add(child as T);        }        else if (child != null)        {            GetVisualChildCollection(child,visualCollection);        }    }}

例如,使用StackPanel作为父面板将非常慢,因为DataGrID可以消耗无限的垂直空间,因此将生成所有行

<StackPanel>    <!-- Slow DataGrID with 20000+ items in ItemsSource -->    <DataGrID ...></StackPanel>

但是使用网格会非常快,因为DataGrID的高度会受到限制,因此可以使用虚拟化

<GrID>    <!-- Fast DataGrID with 20000+ items in ItemsSource -->    <DataGrID ...></GrID>
总结

以上是内存溢出为你收集整理的c# – WPF DataBinding当我使用Convert来格式化日期时非常慢全部内容,希望文章能够帮你解决c# – WPF DataBinding当我使用Convert来格式化日期时非常慢所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1233851.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-06
下一篇2022-06-06

发表评论

登录后才能评论

评论列表(0条)

    保存