用户活动期间不会触发WP7定时器CallBack

时间:2012-02-10 09:53:10

标签: silverlight windows-phone-7 mvvm timer mvvm-light

我有一个为地图点浏览而设计的页面。我想向用户显示边框。这个边框包含User的信息(有点像messagebox一样)。

我使用MVVM模式...

我想在3秒后隐藏边框。一切正常(边界在3秒后隐藏),直到我开始使用地图控件移动。然后边界永远不会隐藏。

附加代码将解释更多......

View中的部分XAML代码:

<Grid>
<my:Map 
    Margin="0,0,0,0" 
    x:Name="MainMap" 
    CredentialsProvider="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
    Center="{Binding MapCenter, Mode=TwoWay}"
    ZoomLevel="{Binding ZoomLevel, Mode=TwoWay}"                     
    myMapViewModel:BindingHelpers.TileSource="{Binding CurrentMap}" 
    myMapViewModel:BindingHelpers.PointsSource="{Binding Points}"
            myMapViewModel:BindingHelpers.CurrentPositionPushpin="{Binding CurrentGeoPosition}"
    myMapViewModel:BindingHelpers.KmlPointSelectedCommand="{Binding ShowSelectedKmlPointCommand}"
    Grid.Row="0"
    CopyrightVisibility="Collapsed"
    ZoomBarVisibility="Collapsed"  
            Padding="0"
    >

    <my:Map.Mode>
        <MSPCMCore:MercatorMode/>
    </my:Map.Mode>

    <TextBlock 
        Grid.Row="0" 
        x:Name="MapNameTile" 
        Text="{Binding CurrentMapName}" 
        Opacity="0.5" 
        Style="{StaticResource PhoneTextNormalStyle}"                    
                    VerticalAlignment="Top"
                    HorizontalAlignment="Left"
                    Canvas.ZIndex="2"
                    Foreground="{StaticResource PhoneAccentBrush}"

                    />
</my:Map>

<Border 
        Canvas.ZIndex="20"                        
        Background="{StaticResource PhoneAccentBrush}" 
        Opacity="0.85"
        Height="100"
        Width="430"
        VerticalAlignment="Top"
        HorizontalAlignment="Center"
        CornerRadius="15"
        Padding="15"
        Margin="0,25,0,0"
        Visibility="{Binding IsInformationPanelVisible, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}"
         >
    <TextBlock 
            Style="{StaticResource PhoneTextNormalStyle}"
            TextWrapping="Wrap"
            Text="{Binding InformationPanelText}"
        />
 </Border>

ViewModel的部分代码:

public bool IsInformationPanelVisible
{
   get
   {
       return this._isInformationPanelVisible;
   }
   set
   {
       if (this._isInformationPanelVisible == value)
       {
            return;
       }

       this._isInformationPanelVisible = value;

       if (this._isInformationPanelVisible)
       {
           new Timer((state) => 
           {
                this.IsInformationPanelVisible = false;         
           }, null, 3000, 0);
       }

       DispatcherHelper.CheckBeginInvokeOnUI(() =>
       {
           RaisePropertyChanged("IsInformationPanelVisible");
       });
   }
}

我的问题是:为什么在用户触摸显示器并移动地图的情况下它不起作用?

无法对其进行调试。

我接受了测试,似乎没有解雇Timer CallBack。

1 个答案:

答案 0 :(得分:2)

这里有几个问题。最大的一个是你的计时器回调lambda中的一个错误 - 你不会在你立即提起它的三秒后引发PropertyChanged事件。你应该在lambda中调用RaisePropertyChanged(在lambda中给出一个lambda!):

   if (this._isInformationPanelVisible)
   {
       new Timer((state) => 
       {
            this.IsInformationPanelVisible = false;        
            DispatcherHelper.CheckBeginInvokeOnUI(() =>
            {
                RaisePropertyChanged("IsInformationPanelVisible");
            });       
       }, null, 3000, 0);
   }

此外,Timer回调(lambda)将在后台线程上运行,后台线程的优先级低于UI线程 - 这是您的更新可能无法触发的另一个原因。

当然,如果你使用DispatcherTimer,你就不会遇到这些问题 - 它总是在UI线程上运行。