加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-17 07:17:11 所属栏目:百科 来源:网络整理
导读:我正在开发一个 WPF应用程序,其中我有一个带网格的ScrollViewer(16个ColumnDefinitions全部自动宽度),并为每列分配一个图像.我想要创建的效果是当鼠标进入ScrollViewer左侧的区域时,图像将向左滚动…当鼠标进入ScrollViewer右侧的区域时,它们向右滚动.滚动条
我正在开发一个 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的方法是创建一个特殊的委托并调用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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读