WP7 Timer CallBack не срабатывает во время активности пользователя - PullRequest
0 голосов
/ 10 февраля 2012

У меня есть страница, предназначенная для просмотра точек на карте. Я хочу показать границу пользователю. эта граница содержит информацию для пользователя (она похожа на окно сообщения).

Я использую паттерн MVVM ...

Я хочу скрыть границу через 3 секунды. Все работает (граница скрыта через 3 секунды), пока я не начну двигаться с контролем карты. Тогда граница никогда не скроется.

Прикрепленный код объяснит больше ...

Часть моего кода 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 Ответ

2 голосов
/ 10 февраля 2012

Здесь есть пара проблем. Самая большая из них - ошибка в лямбде обратного вызова таймера - вы не вызываете событие PropertyChanged через три секунды, а сразу же вызываете его. Вы должны иметь вызов RaisePropertyChanged внутри вашей лямбды (давая лямбду внутри лямбды!):

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

Кроме того, обратный вызов Timer (lambda) будет выполняться в фоновом потоке, который имеет более низкий приоритет, чем поток пользовательского интерфейса - это еще одна причина, по которой ваше обновление может не запускаться.

Конечно, если вы используете DispatcherTimer, у вас не возникнет ни одной из этих проблем - он всегда работает в потоке пользовательского интерфейса.

...