2012-03-23 102 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