我需要在主界面从服务器接收信息,然后在子界面展示出来(实时曲线).数据处理是用的委托,主界面接收到信息后调用.
子界面处理方式:将从服务器接收到的消息处理后存为一个集合(A).自定义一个控件,控件里面的Polyline绑定一个集合(B),用定时器将A中的数据放在B中.
这是第一次进入子界面的曲线
这是退出子界面然后再次进入时的曲线
开始我以为是定时器的问题,因为子界面关闭后定时器还在跑(但如果真的是定时器问题,我每次打开子界面都是new的一个对象,当前对象应该只有一个定时器啊).
然后我将这些数据集合全部放在一个静态类中,定时器也是静态的,结果还是这样.
恭喜正确认识到wpf的UI.Timer,它跟winForm的UI.Timer确实不一样;
所以你可以手动去销毁~~或者直接全局用一个。
用的是DispatcherTimer,静态的,每次打开子界面都会重置一下定时器(先关闭,在打开,不知道对不对.)但还是会出现这种情况.
下面是定时器代码:
if (SignTape_HX.Count > 0)
{
int o = SignTape_HX.Count / 16;
if (o > 8)
{
o = 10;
}
for (int i = 0; i < o; i++)
{
CoordinatePoints_HX.Add(SignTape_HX[i]);
if (CoordinatePoints_HX.Count > 150)
{
AddCurvePoint_SignTapeHX();
}
SignTape_HX.RemoveRange(0, o);
}
}
if (SignTape_XL.Count > 0)
{
int o = SignTape_XL.Count / 10;
if (o > 16)
{
o = 14;
}
for (int i = 0; i < o; i++)
{
CoordinatePoints_XL.Add(SignTape_XL[i]);
if (CoordinatePoints_XL.Count > 1538)
{
AddCurvePoint_SignTapeXL();
}
}
SignTape_XL.RemoveRange(0, o);
}
@请假一天: 那些得到这么复杂,为UI.Points增加一个AddMaxLen函数,
AddMaxLen(points,maxLen):
points.Foreache(t=>{
_ui.Points.Add(t);
while(_ui.Points.Len>maxLen)
_ui.Points.Remove(0);
});
注意过程化思路,对象化思路。
全局的话,根本不需要怎么开开关关,进入后Load直接给XXTick回调赋值就行了,UnLoad的时候XXTick=Null就OK。
@花飘水流兮: 感谢您的回答,不过我试了下,还是无法解决这个问题.是每次打开子界面(其实是一个控件,继承的UserControl),就会多一个定时器来控制这个集合(B),同一时间有两个定时器项里面加数据,更奇怪的是界面上显示的曲线长度会增加一倍,但是MaxLength的值没有变.
@请假一天: 都给你说了一个,要么去销毁,还在两个,这跟winForm不一样,winForm是作为Component封装,在容器内,而这不是,这是根下的Dispatcher出来实现(具体这个细节没有详细看)的。
给了你个简单了办法:
Action OnGloableTick;
Tick += (o,e)=>{OnGloableTick.Invoke()};
用:
开:OnGloableTick = Ui.Update();
关:OnGloableTick = null;
最好不要去用+=;
@请假一天: 你就当线程时钟,线程时钟怎么处理~~难道不Dispose?
@花飘水流兮: 谢谢您的解答,因为刚接触定时器这块,所以很多地方那个不懂,最开始一直以为退出控件定时器就会被回收的