wpf - 尝试以编程方式滚动滚动查看器

标签 wpf vb.net timer scrollview

我正在开发一个 WPF 应用程序,其中我有一个带有网格的 ScrollViewer(16 个 ColumnDefinitions 所有自动宽度),每个列都有一个图像。我想要创建的效果是当鼠标进入 ScrollViewer 左侧的区域时,图像将滚动到左侧......当鼠标进入 ScrollViewer 右侧的区域时,它们会滚动到右侧。滚动条将被隐藏。左侧和右侧的区域由两个带有 mouseEnter 和 mouseLeave 事件的矩形定义。我背后的代码利用计时器以编程方式向左或向右滚动 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

如果我从 Expressions Blend 运行此项目,则项目构建正常并显示,但滚动操作不起作用。

如果我从 Visual Studio 运行它,我会收到一条错误消息...
svImages.ScrollToHorizontalOffset(svImages.HorizontalOffset - 0.1)

说 InvalidOperationException 未被用户代码处理...调用线程无法访问此对象,因为不同的线程拥有它。我什至在窗口加载之前收到此错误。

我哪里错了。

最佳答案

错误“调用线程无法访问此对象,因为不同的线程拥有它。”对于 WinForms 和 WPF 控件来说是相当标准的。

在 WPF 和 WinForms 中,窗口使用一个特定的线程呈现在屏幕上,通常称为 UI 线程。每个关于控件的更新/更改操作都应在该线程上进行以取得成功。

使用 WinForms 的通常方法是创建一个特殊的委托(delegate)并调用 Control.Invoke,如 link 所示。 .

在 WPF 中,使用 Dispatcher 可以达到相同的效果。 .您的代码应如下所示:

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

更新:

我有以下代码可以在 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

关于wpf - 尝试以编程方式滚动滚动查看器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9846355/

相关文章:

javascript - JavaScript/jQuery 倒计时器最简单的解决方案

c# - 光标在模板化文本框中不闪烁

sql-server - 使用存储过程从 vb.net 传递参数

.net - VB.NET 扩展方法

vb.net - 在 StartUp 文件夹中创建快捷方式 (VB.NET)

c# - 服务中的定时器

timer - 使用 Swift 3 停止预定定时器,即使定时器为零,定时器也会继续触发

wpf - 如何在不知道进度动画的完成度的情况下显示进度动画?

wpf RowDetailsTemplate焦点

c# - WPF TextBox 在 Tab 焦点上全选