【问题标题】:Time Trackbar or Very Large Values using Trackbar使用 Trackbar 的时间 Trackbar 或非常大的值
【发布时间】:2016-05-03 21:42:22
【问题描述】:

我正在使用 GMAP.NET 编写一个车辆跟踪应用程序

我想根据日期/时间显示多个车辆标记的同时移动。

为此,我想使用一个 Trackbar,这样当用户滑动 trackbar 时,会显示多个标记的相应移动。

我在浏览器上做了同样的应用,效果很好。我将标记标记的日期时间属性转换为 UNIX 时间戳,然后将轨迹栏(NOUI 滑块)值设置为 UNIX 时间戳范围。

但是,现在我发现使用 Windows 桌面 C# Trackbar 根本无法做到这一点。

问题是:

  1. 轨迹栏无法获取非常大的时间戳值。例如。 5年数据。

  2. 即使减少了非常大的数字,trackbar 仍然无法获取如此高的值,并且一直滞后或崩溃。

例如。我需要显示 5 年的数据。在这种情况下,我的轨迹栏将具有最小值 - 1262304000(即 01-01-2010)到 1425203100(即 01-03-2015 | 09:45)。

但是如此大的值不适用于我的轨迹栏。

我什至采取了减少,例如。将 1262304000 设置为 1,然后 162899100(即 1425203100 - 1262304000)成为我的最大值。

但即使这样也非常密集,并且轨迹栏不起作用。

请建议是否有一个时间轨迹栏可以显示非常大的日期时间范围,或者我如何使用具有非常大值的常规轨迹栏。

代码如下——

A.将日期时间转换为 UNIX 时间戳的函数

    public Int32 UnixTimeStampUTC(DateTime datetime)
    {
        Int32 unixTimeStamp;

        DateTime zuluTime = datetime.ToUniversalTime();
        DateTime unixEpoch = new DateTime(1970, 1, 1).ToUniversalTime();
        unixTimeStamp = (Int32)(zuluTime.Subtract(unixEpoch)).TotalSeconds;
        return unixTimeStamp;
    }

B.通过连接日期和时间列并添加第三列来保存日期时间列的 Unix 时间戳,从数据表中获取日期时间

            for (int z = 0; z < dt.Rows.Count; z++)
            {

                if (reviseddt.Rows[z]["date"].ToString() != "")
                {
                    dte = DateTime.Parse(reviseddt.Rows[z]["date"].ToString());

                    dteticks = UnixTimeStampUTC(dte);

                }
                else
                {
                    dteticks = 0;
                }

                if (reviseddt.Rows[z]["time"].ToString() != "")
                {
                    tm = DateTime.Parse(reviseddt.Rows[z]["time"].ToString());

                    tmticks = UnixTimeStampUTC(tm);
                }
                else
                {
                    tmticks = 0;
                }


                Int32 fullDt = dteticks + tmticks;

                reviseddt.Rows[z]["datetime"] = fullDt.ToString();
                reviseddt.Rows[z]["datetimestring"] = reviseddt.Rows[z]["date"].ToString() + reviseddt.Rows[z]["time"].ToString();

C.通过从数据表中的日期时间列中获取最小值和最大值,然后将范围作为最小值和最大值之间的差异来初始化 Trackbar。因此,Trackbar range = 1 to (Max-Min)

string strminlevel = toplotDataTable.Compute("min(datetime)", String.Empty).ToString();
string strmaxLevel = toplotDataTable.Compute("max(datetime)", String.Empty).ToString();

Int32 minLevel = Convert.ToInt32(strminlevel);
Int32 maxLevel = Convert.ToInt32(strmaxLevel);

Int32 rangeint = maxLevel - minLevel;

trackBarMoveTarget.Maximum = rangeint;
trackBarMoveTarget.Minimum = 1;
trackBarMoveTarget.LargeChange = 100;
trackBarMoveTarget.SmallChange = 1;

【问题讨论】:

  • 请向我们展示您的代码!您应该阅读How to Askminimal reproducible example
  • 感谢您的评论。但我认为代码在这里不会有任何区别。我的代码有什么作用? 1. 将 datetime 转换为 Unix Timestamp(常用函数我脱网) 2. 设置 Trackbar 的范围 --> 我的基本问题是 trackbar 如何处理非常大的值?还是有其他方法?
  • 您应该始终发布您的代码。这是正确的礼仪。尽管如此,我会给你一个提示 - LargeChangeSmallChangeTickFrequency
  • 另外,既然你不知道如何解决这个问题,你不应该草率​​地得出代码没有帮助的结论。事实上,当我们回答问题时,我们喜欢minimal reproducible example,这样我们就可以看到您的问题,然后我们可以在发布之前验证我们的答案是否正确。
  • 感谢您的评论。热情。 :) 请参考 Ubercoder 下面的 cmets,如果您能以这种方式提供帮助,请告诉我。 :) 真的卡在这里!

标签: c# winforms datetime trackbar gmap.net


【解决方案1】:

现实一点 - 轨迹栏的分辨率只有 1 像素 - 大多数显示器的宽度最多为 1920 像素。因此,分辨率只需 1920 - 让我们四舍五入到 2000。

现在您有一个 5 年周期 = 5 * 365 + 1(奇数闰年)= 1826。这几乎等于我们最初的 2000 奇数。所以让我们把它设为 1826。

因此将最小值设置为 0,将最大值设置为 1826。

当您获得跟踪事件时,您将第一个日期 01-01-2010 并将跟踪栏的值添加到它:

var firstDate = new DateTime(2010, 1, 1).Date;

var trackDate = firstDate + TimeSpan.FromDays(trackBar.Value);

简单快捷。

【讨论】:

  • 感谢您的解决方案。如果值只有几天,这将完美地工作。但就我而言,它是精确到分钟的。典型值为“01-01-2013 09:35”。请指教。
  • 一开始,轨迹栏不可能在 5 年的时间里有几分钟甚至几小时的分辨率。它受到具有屏幕分辨率限制的 UI 的限制。它具有有限数量的位置,您可以将轨迹栏滑动到这些位置。这个数字大约是 1900。所以你只能将你的五年时间分成大约一天多一点的部分。
  • 感谢您的澄清,非常感谢您抽出时间提供帮助。但是 JQuery 滑块是如何工作的呢?我使用了 NoUISlider (refreshless.com/nouislider),当应用程序基于浏览器且具有相同的 5 年日期时间范围时,它运行良好。
  • Ubercoder:嗨!抱歉,由于我没有声誉,因此无法为您的答案评分。 (我不知道它怎么说-1)谢谢。我已经意识到轨迹栏有一个限制,必须使用你的和@Enigmativity 的解决方案来解决它。
【解决方案2】:

在这种规模下使用TrackBar 有两个问题。

首先您需要能够左右移动轨迹栏,但如果SmallChangeLargeChange 属性太小,那么您可能会取得很大进展,但它根本不会显示轨迹栏。试试这个:

trackBarMoveTarget.Maximum = rangeint;
trackBarMoveTarget.Minimum = 1;
trackBarMoveTarget.LargeChange = rangeint / 50;
trackBarMoveTarget.SmallChange = rangeint / 200;

另一个问题是TrackBar 控件试图沿其长度呈现有用的小刻度线。默认情况下,TickFrequency1Maximum 的值是 10。当您将Maximum 设置为162899100 而不更改TickFrequency 时,可怜的TrackBar 控件必须尝试渲染162899100 刻度线,这需要很长时间。试试这个:

trackBarMoveTarget.TickFrequency = rangeint / 100;

【讨论】:

  • 嗨!谢谢你的提示。我正在使用您的两个答案进行变通。 :) 因为 trackbar 有限制,我现在明白了。我的应用程序中有很多繁重的 UI 工作,因为多个标记会根据轨迹条的移动沿地图重绘。我会努力减少这种情况。此外,由于我没有足够的声誉,无法获得答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多