1

SilverlightでMVVMを使用しようとしていますが、まったく新しいので、いくつかの点についてはよくわかりません。サーバー側の操作の進行状況を表示するSilverlightページがあります。現在の進捗状況はWebサービスからのものであり、数秒ごとに更新する必要があります(議論のために10秒としましょう)。

これを実装するための最良の方法は何ですか?私が考えることができたオプションは次のとおりでした:

  1. ViewModelのInitalizeメソッドでDispatcherTimerを初期化し、DispatcherTimerイベントからビューを更新します(タイマーの詳細をViewModelに入れます)

  2. DispatcherTimer(PeriodicCommandExecutorなど)の周りにラッパーを作成します。これは、ViewModelのRefreshコマンドにバインドするコマンドプロパティを使用して、WindowsFormsのタイマーコントロールと同様のコントロールまたはリソースになります(タイマーの詳細をビューに配置します)

2番目のオプションが好ましいと思います。これは、ViewModelのテストが容易になり、DispatcherTimerがViewModelに適切に望まないUI実装の詳細であるためです。同意しますか?

はいの場合、そのようなラッパーをどのように作成しますか。プロパティがアタッチされたDependencyObjectの実行を開始しましたが、Intervalなどのプロパティ値を内部のDispatcherTimerに転送する方法がわかりません。依存関係のプロパティが変更され、DispatcherTimerがDependencyObjectでない場合、Silverlightはイベントを提供しないようです。そのため、そのプロパティに直接データバインドすることはできません。

ありがとう!

4

2 に答える 2

0

DispatcherTimer を使用する理由 バックグラウンド スレッドでコールバックを起動する通常のSystem.Threading.Timerを使用しないのはなぜですか?

UI の進行状況の更新を目立たない場所 (つまり、UI の中央ではなく、下隅やステータス バーなど) に配置した場合、ユーザーが行っていたことを続行している間、バックグラウンド タイマーが動作しなくなります。進行状況の値をビューモデルに入力し、バインディングを使用して UI に表示できます。この方法では、Web サービス呼び出しを行う UI スレッドを結び付ける必要がありません。

于 2011-05-06T10:54:55.647 に答える
0

最後に、指定できるViewModelで更新コマンドを定期的に実行する動作を作成して、ジレマを解決しました。

動作のコードは次のようになります (VB コードで申し訳ありません)。

Option Strict On

Imports System.Windows.Threading
Imports System.Windows.Interactivity

Namespace View.Behaviors

    Public Class RefreshBehavior
        Inherits Behavior(Of FrameworkElement)



        Public Property Command As ICommand
            Get
                Return DirectCast(GetValue(CommandProperty), ICommand)
            End Get

            Set(ByVal value As ICommand)
                SetValue(CommandProperty, value)
            End Set
        End Property

        Public Shared ReadOnly CommandProperty As DependencyProperty = _
                                   DependencyProperty.Register("Command", _
                                                               GetType(ICommand), GetType(RefreshBehavior), _
                                                               New PropertyMetadata(Nothing))


        Public Property CommandParameter As Object
            Get
                Return GetValue(CommandParameterProperty)
            End Get

            Set(ByVal value As Object)
                SetValue(CommandParameterProperty, value)
            End Set
        End Property

        Public Shared ReadOnly CommandParameterProperty As DependencyProperty = _
                                   DependencyProperty.Register("CommandParameter", _
                                                               GetType(Object), GetType(RefreshBehavior), _
                                                               New PropertyMetadata(Nothing))




        Public Property Interval As TimeSpan
            Get
                Return DirectCast(GetValue(IntervalProperty), TimeSpan)
            End Get

            Set(ByVal value As TimeSpan)
                SetValue(IntervalProperty, value)
            End Set
        End Property

        Public Shared ReadOnly IntervalProperty As DependencyProperty = _
                                   DependencyProperty.Register("Interval", _
                                                               GetType(TimeSpan), GetType(RefreshBehavior), _
                                                               New PropertyMetadata(TimeSpan.Zero, AddressOf OnIntervalUpdate))



        Public Property Enabled As Boolean
            Get
                Return DirectCast(GetValue(EnabledProperty), Boolean)
            End Get

            Set(ByVal value As Boolean)
                SetValue(EnabledProperty, value)
            End Set
        End Property

        Public Shared ReadOnly EnabledProperty As DependencyProperty = _
                               DependencyProperty.Register("Enabled", _
                               GetType(Boolean), GetType(RefreshBehavior), _
                               New PropertyMetadata(False, AddressOf OnEnabledUpdate))




        Dim WithEvents timer As New DispatcherTimer()

        Private Shared Sub OnEnabledUpdate(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            Dim enable As Boolean = CType(e.NewValue, Boolean)
            Dim executor As RefreshBehavior = CType(d, RefreshBehavior)
            If Not executor.attached Then Return

            Dim timer As DispatcherTimer = executor.timer

            If enable AndAlso Not timer.IsEnabled Then
                timer.Start()
            ElseIf Not enable AndAlso Not timer.IsEnabled Then
                timer.Stop()
            End If
        End Sub

        Private Shared Sub OnIntervalUpdate(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
            Dim executor As RefreshBehavior = CType(d, RefreshBehavior)

            Dim timer As DispatcherTimer = executor.timer
            timer.Interval = CType(e.NewValue, TimeSpan)
        End Sub

        Private WithEvents attachedObject As FrameworkElement

        Private Sub OnUnload(ByVal sender As Object, ByVal e As EventArgs) Handles attachedObject.Unloaded
            timer.Stop()
        End Sub

        Private attached As Boolean = False
        Protected Overrides Sub OnAttached()
            attached = True
            attachedObject = AssociatedObject

            If Enabled Then timer.Start()
            MyBase.OnAttached()
        End Sub

        Protected Overrides Sub OnDetaching()
            timer.Stop()
            attached = False
            attachedObject = Nothing
            MyBase.OnDetaching()
        End Sub

        Private Sub OnTick(ByVal sender As Object, ByVal e As EventArgs) Handles Timer.Tick
            Dim cmd = Command
            Dim parameter = CommandParameter
            If Interval < TimeSpan.MaxValue AndAlso cmd IsNot Nothing AndAlso cmd.CanExecute(parameter) Then
                cmd.Execute(parameter)
            End If
        End Sub
    End Class
End Namespace

次のように使用できます。

<i:Interaction.Behaviors>
    <Behaviors:RefreshBehavior Enabled="True" Interval="0:0:10" Command="{Binding RefreshPageCommand}" />
</i:Interaction.Behaviors>

同様の問題を抱えている人に役立つことを願っています。

于 2011-06-27T23:09:04.500 に答える