首页 \ 问答 \ 无法在WPF TextBlock中获得垂直滚动条(Unable to get vertical scroll bars in an WPF TextBlock)

无法在WPF TextBlock中获得垂直滚动条(Unable to get vertical scroll bars in an WPF TextBlock)

我在wpf TextBlock控件(.Net 3.5)中呈现文本。 文本块的内容取决于用户在列表框中选择的内容。 文字包装,所以我不需要水平滚动条。 但是,通常有更多的文本不能显示窗口的数量,所以我需要一个垂直滚动条。

在我开始搜索时,我很快发现答案是将TextBlock包装在ScrollViewer中。 但是,它不工作(TM),我希望有人可以帮我找出原因。

这是UI代码的结构:

<Window x:Class=..>
    <StackPanel>
        <ListBox HorizontalAlignment="Stretch"
                 VerticalAlignment="Top"  Height="200"
                 SelectionChanged="listbox_changed" SelectionMode="Single">
        </ListBox>
        <Button Click="Select_clicked">Select</Button>
        <ScrollViewer VerticalScrollBarVisibility="Auto">
            <TextBlock Name="textblock" TextWrapping="Wrap"/>
        </ScrollViewer>
    </StackPanel>
</Window>

当用户在列表框中选择一个项目时,与该项目相关的一些文本将显示在TextBlock中。 我原以为代码应该是所有必需的,但它从来没有给我提供一个滚动条。

搜索和实验给了我两个线索:问题的根源可能与我动态更新TextBlock的内容有关,并且TextBlock不会根据新内容调整自身的大小。 我发现一个似乎相关的帖子,说通过将TextBlock的高度设置为其ActualHeight(在更改其内容之后),它将起作用。 但它没有(我看不到这个效果)。

其次,如果我设置ScrollViewer的高度(在设计时间内),那么我会得到一个垂直滚动条。 例如,如果我在上面的xaml中将它设置为300,那么结果几乎是好的,因为当我需要它时,第一次打开的窗口包含一个带有垂直滚动条的TextBlock。 但是,如果我使窗口更大(在运行时用鼠标调整大小),ScrollViewer不会利用新的窗口大小,而是根据xaml保持其高度,当然这不会。

希望我只是忽略了一些显而易见的事情。

谢谢!


I'm presenting text in a wpf TextBlock control (.Net 3.5). The content of the textblock varies depending on what the user selects in a list box. The text wraps, so I don't need an horizontal scroll bar. However, there is often more text than the amount the window can display, so I need a vertical scroll bar.

As I started searching I quickly found that the answer is to wrap the TextBlock in a ScrollViewer. However, It Does Not Work (TM) and I'm hoping someone can help me work out why.

This is the structure of the UI code:

<Window x:Class=..>
    <StackPanel>
        <ListBox HorizontalAlignment="Stretch"
                 VerticalAlignment="Top"  Height="200"
                 SelectionChanged="listbox_changed" SelectionMode="Single">
        </ListBox>
        <Button Click="Select_clicked">Select</Button>
        <ScrollViewer VerticalScrollBarVisibility="Auto">
            <TextBlock Name="textblock" TextWrapping="Wrap"/>
        </ScrollViewer>
    </StackPanel>
</Window>

When the user selects an item in the list box, some text associated with this item is presented in the TextBlock. I would have thought that the code as it stands should have been all that's required, but it never provides me with a scroll bar.

Searching and experimenting have given me two clues: the root of the problem might be related to me updating the content of the TextBlock dynamically, and that the TextBlock does not resize itself based on the new content. I found a posting that seemed relevant that said that by setting the Height of the TextBlock to its ActualHeight (after having changed its content), it would work. But it didn't (I can see no effect of this).

Second, if I set the height (during design time) of the ScrollViewer, then I do get a vertical scroll bar. For instance, if I set it to 300 in the xaml above, the result is almost good in that the window as first opened contains a TextBlock with a vertical scroll bar when (and only when) I need it. But if I make the window larger (resizing it with the mouse during runtime), the ScrollViewer does not exploit the new window size and instead keeps its height as per the xaml which of course won't do.

Hopefully, I've just overlooked something obvious..

Thanks!


原文:https://stackoverflow.com/questions/5621086
更新时间:2022-06-23 20:06

最满意答案

你不能真正暂停在未来的身体中间,但你可以将你的未来注册为“延迟”未来的后续,你可以将其定义为:

def delay(milliseconds: Int): Future[Unit] = {
  val p = Promise[Unit]()
  js.timers.setTimeout(milliseconds) {
    p.success(())
  }
  p.future
}

然后您可以将其用作:

val readyLater = for {
  delayed <- delay(1000)
} yield {
  println("ready")
}

You cannot really pause in the middle of the future body, but you can register your future as a followup to a "delay" Future, which you can define as:

def delay(milliseconds: Int): Future[Unit] = {
  val p = Promise[Unit]()
  js.timers.setTimeout(milliseconds) {
    p.success(())
  }
  p.future
}

and which you can then use as:

val readyLater = for {
  delayed <- delay(1000)
} yield {
  println("ready")
}

相关问答

更多
  • 我成功使用的一种方法涉及3个sbt项目和一个静态内容的根目录下的附加文件夹: . ├── build.sbt ├── client ├── server ├── shared └── static 在build.sbt ,你会使用如下的东西: lazy val sharedSettings = Seq( // File changes in `/static` should never trigger new compilation watchSources := watchSources.val ...
  • 对于任何其他JavaScript API,您基本上可以使用动态类型API使用js.Dynamic或(可能是手写)类型的Facade访问它。 在这种情况下,我建议第一部分使用动态API: import scala.scalajs.js import js.Dynamic.{global => g, literal => lit} g.gapi.load("auth", lit(callback = onAuthApiLoad)) g.gapi.load("picker", lit(callback = on ...
  • 你不能真正暂停在未来的身体中间,但你可以将你的未来注册为“延迟”未来的后续,你可以将其定义为: def delay(milliseconds: Int): Future[Unit] = { val p = Promise[Unit]() js.timers.setTimeout(milliseconds) { p.success(()) } p.future } 然后您可以将其用作: val readyLater = for { delayed <- delay(1000) } ...
  • 鉴于你有一个Uint8ClampedArray ,这是一个JavaScript类型,Scala.js不保证在运行时它确实拥有一个Uint8ClampedArray值。 在这种情况下,您确实可以使用 js.typeOf(x) == "undefined" 甚至 (x: Any) == js.undefined “推荐”方式是使用 js.isUndefined(x) 但其他的一样正确。 顺便说一句:你在评论中说,JavaScript代码确实ex$1 = undefined 。 这是未定义的行为 ,并将在f ...
  • 假设您正在调用阻止Future代码: 因为Future使用ExecutionContext 。 是否意味着,在执行其中的代码时,此线程池中的某些线程将被此未来阻止? 基本上,是的。 如果您正在调用阻止代码,则必须阻止某些内容 。 但是, ExecutionContext比线程池更通用。 它可以是线程池,但它也可以是以其他方式管理调用的东西。 仍然会阻止某些东西,通常情况下它会成为一个主题。 例如, scala.concurrent.ExecutionContext.Implicits.global是一个Fo ...
  • 我认为不可能使用Play! Scala.js中的模板还没有。 问题是编译玩! 模板指Play! 图书馆,包括 import play.templates._ import play.templates.TemplateMagic._ import play.api.templates._ import play.api.templates.PlayMagic._ import play.api.i18n._ import play.api.mvc._ import play.api.data._ 这些只是 ...
  • Scala.JS无法自动将JS对象转换为Scala案例类。 您需要定义一个外观。 请参阅此文档。 它应该看起来像这样: @js.native trait UserSignup extends js.Object { def firstName: String = js.native def lastName: String = js.native ... } Scala.JS can't automatically convert a JS Object to Scala case clas ...
  • 执行脚本后, get_browser_info就像任何JavaScript库一样,从Scala.js的角度来看。 因此,您可以以动态类型的方式调用它,如下所示: val browser = js.Dynamic.global.get_browser_info() val name = browser.name.asInstanceOf[String] val version = browser.version.asInstanceOf[String] 或者您可以定义您喜欢的静态类型外观。 Once the ...
  • 首先,请务必阅读JS interop doc ,包括调用JavaScript指南 。 我想你已经这样做了,因为你已经有了一些合理的东西。 但是除非明确提到,否则你应该特别注意那些说Scala类型和JavaScript类型完全不相关的部分。 因此, Int是一个合适的JS number (在int的范围内)。 但是Array[Point]与JavaScript数组无关。 Tuple2 (如(1, 3) )甚至更少。 所以: Point的定义是否被翻译成具有两个组件的js数组? 不它不是。 因此,JavaScr ...
  • Uglify以uglify uglify-js ,而不是uglifyjs 。 此外,没有为2.7.4版本创建webjar,但是有2.7.5版本。 如果您需要特定版本,只需点击几下http://www.webjars.org/npm即可轻松请求自动创建2.7.4的webjar。 如果你去webjars网站搜索“uglify-js”,你会看到你需要使用的依赖配置: "org.webjars.npm" % "uglify-js" % "2.7.5" (加上你想要的文件)。 请注意,从0.6.14开始,Scala. ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)