2012-03-23 146 views
4

我正在開發一個WPF應用程序,其中我有一個ScrollViewer與網格(16 ColumnDefinitions所有自動寬度)與圖像分配給每列。我想創建的效果是,當鼠標進入ScrollViewer左側的區域時,圖像將滾動到左側......並且當鼠標進入ScrollViewer右側的區域時,它們向右滾動。滾動條將被隱藏。左邊和右邊的區域由兩個帶有mouseEnter和mouseLeave事件的矩形定義。我後面的代碼利用計時器以編程方式向左或向右滾動ScrollViewer。試圖以編程方式滾動scrollviewer

這裏是我的代碼...

Imports System 
Imports System.IO 
Imports System.Net 
Imports System.Windows 
Imports System.Windows.Controls 
Imports System.Windows.Data 
Imports System.Windows.Media 
Imports System.Windows.Media.Animation 
Imports System.Windows.Navigation 


Partial Public Class Crime 

    Dim ScrollLeft As Boolean = True 
    Dim atimer As New System.Timers.Timer() 

    Public Sub New() 
     MyBase.New() 

     Me.InitializeComponent() 

     ' Insert code required on object creation below this point. 

     ' Hook up the Elapsed event for the timer. 
     AddHandler atimer.Elapsed, AddressOf Me.timer_Tick 

     atimer.Interval = 100 
     atimer.Enabled = True 

    End Sub 

    'CODE TO SCROLL SCROLLVIEWER PROGRAMATICALLY 
    Private Sub timer_Tick(sender As Object, e As EventArgs) 
     If ScrollLeft Then 
      svImages.ScrollToHorizontalOffset(svImages.HorizontalOffset - 1) 
     Else 
      svImages.ScrollToHorizontalOffset(svImages.HorizontalOffset + 1) 
     End If 
    End Sub 

    Private Sub Left_MouseEnter(sender As Object, e As MouseEventArgs) 
     ScrollLeft = True 
     atimer.Start() 
    End Sub 

    Private Sub Right_MouseEnter(sender As Object, e As MouseEventArgs) 
     ScrollLeft = False 
     atimer.Start() 
    End Sub 

    Private Sub Left_MouseLeave(sender As Object, e As MouseEventArgs) 
     atimer.Stop() 
     ScrollLeft = True 
    End Sub 

    Private Sub Right_MouseLeave(sender As Object, e As MouseEventArgs) 
     atimer.Stop() 
    End Sub 

End Class 

如果我跑這從式混合生成項目確定和顯示器,但滾動動作,是行不通的。

如果我運行這個從Visual Studio我得到一個錯誤與線...

svImages.ScrollToHorizontalOffset(svImages.HorizontalOffset - 0.1) 

說InvalidOperationException異常是由用戶代碼未處理的......因爲不同的線程擁有調用線程不能訪問該對象它。在窗口加載之前,我得到這個錯誤。

我哪裏出錯了。

回答

8

錯誤「調用線程無法訪問此對象,因爲不同的線程擁有它。」對於WinForms和WPF控件來說是非常標準的。

在WPF和WinForms窗口中,使用一個特定線程(通常稱爲UI線程)在屏幕上呈現窗口。關於控制的每個更新/更改操作都應在該主題上進行,以取得成功。

WinForms的常用方法是創建一個特殊的委託並調用Control.Invoke,如link所示。

從WPF開始,使用Dispatcher可以達到同樣的效果。您的代碼應該是這樣的:

this.Dispatcher.Invoke(() => svImages.ScrollToHorizontalOffset(svImages.HorizontalOffset - 0.1)); 

UPDATE:

我有下面的代碼在VB.NET的工作:

Private Delegate Sub ScrollDelegate(ByVal offset As Double) 

Private Sub ScrollLeft(ByVal offset As Double) 
    svImages.ScrollToHorizontalOffset(svImages.HorizontalOffset + offset) 
End Sub 

// ... calling from background thread 

Dim slt As ScrollDelegate 
slt = New ScrollDelegate(AddressOf ScrollLeft) 
Me.Dispatcher.Invoke(slt) 

更新2

關於該問題的代碼已更改。

Dim ScrollLeft As Boolean = True 
Dim atimer As New System.Timers.Timer() 
Dim scrollMethod As ScrollDelegate 
Private Delegate Sub ScrollDelegate(ByVal offset As Double) 

// ... 
    Me.InitializeComponent() 
    slt = New ScrollDelegate(AddressOf DoScroll) 

// ... 

Private Sub timer_Tick(sender As Object, e As EventArgs) 
    If ScrollLeft Then 
     Me.Dispatcher.Invoke(slt, -1) 
    Else 
     Me.Dispatcher.Invoke(slt, 1) 
    End If 
End Sub 

// ... 

Private Sub DoScroll(ByVal offset As Double) 
    svImages.ScrollToHorizontalOffset(svImages.HorizontalOffset + offset) 
End Sub 
+0

-1你的代碼的失敗在Visual Studio編譯VS 2010中說:「預計宣言」 – user774411 2012-03-24 10:15:57

+0

@Down啦啦高科技我只給了一個片斷..聲明暗淡ScrollLeft由於布爾=真和點心atimer作爲New System.Timers.Timer() – Mych 2012-03-24 10:43:40

+0

@Dmitriy Reznik。我已經將您的建議轉換爲VB,它使Me.Dispatcher.Invoke(函數()svImages.ScrollToHorizo​​ntalOffset(svImages.Horizo​​ntalOffset - 0.1))不幸的是部分svImages.ScrollToHorizo​​ntalOffset(svImages.Horizo​​ntalOffset - 0.1顯示與VS2010中的藍色波浪線和提示說Expression不會產生任何值...任何建議... – Mych 2012-03-24 10:48:04