无法在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
最满意答案
你不能真正暂停在未来的身体中间,但你可以将你的未来注册为“延迟”未来的后续,你可以将其定义为:
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") }
相关问答
更多-
服务Scala.js资产(Serving Scala.js assets)[2024-01-16]
我成功使用的一种方法涉及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 ...
-
Scala Future [T]内部是否阻止?(Does Scala Future[T] block internally? What happens inside Scala Future?)[2022-04-25]
假设您正在调用阻止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. ...