繁体   English   中英

修改TextBox ControlTemplate以限制滚动,运行时属性设置不正确

[英]Modifying TextBox ControlTemplate to limit scrolling, property settings aren't correct at runtime

我在为TextBox定制ControlTemplate遇到问题 这个想法是自动在整齐的纸上自动整齐地打印文本,并尽可能减少用户交互,同时在文本长度,字体大小等方面保持尽可能灵活。

为此,一个设置是相对于打印行的文本高度(距它在纸上显示的行的距离近/远)。 由于更改TextBox LineHeight会在文本下方而不是上方添加空间,因此我一直在使用文本框顶部的Padding向下转换文本。

每当指定的LineHeight大于文本框内的剩余可见空间时,就会引起问题。 可能会无意间向下滚动到该行的底部,从而导致文本向上滚动到填充区域并消失。

要解决此问题,我需要防止MouseWheel / PgUp / PgDwn在文本框内滚动,或者弄清楚如何沿一行的底部边缘而不是顶部呈现文本。

使用Snoop,我发现TextBox控件具有ScrollContentPresenter其CanContentScroll属性由ScrollViewer ParentTemplate确定。 在应用程序运行时,在Snoop中取消选中CanContentScroll会禁用滚动,并按照我的意愿阻止此行为,但是由于某些原因,在模板中指定CanContentScroll = False确实可行。 它仍然是True

XAML:

<TextBox.Style>
    <Style TargetType="TextBoxBase">
        . . . 
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TextBoxBase}">
                    <theme:ListBoxChrome x:Name="Bd" . . . >
                        <ScrollViewer x:Name="PART_ContentHost"
                                      CanContentScroll="False"/>
                    </theme:ListBoxChrome>
                    . . . 
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</TextBox.Style>

可以直接从Microsoft的WPFThemes / Aero.NormalColor.xaml提取样式,而对controltemplate进行一次更改即可禁用滚动。 对其他(省略)设置器的更改(例如背景色)确实可行。 我直接在TextBox中指定了样式,因为它不会在其他任何地方使用,并且假定局部样式先于隐式样式出现,但是我猜测这可能不是执行此操作的正确位置。

谁能指出我对此有何疑问,或确认是否可以更改文本在一行上的显示位置?

谢谢

编辑:这是对此TextBox实际所做的更好的描述

假设您有一个纸质表格,例如贷款或许可申请,其中有几个问题,每个问题都有3个预打印的行,可在上面写下您的答案。 文字框:

  • 确定大小/位置以覆盖整个答案区域
  • 设置为包含3行
  • 提供用户字体大小,对齐方式,字体选项
  • 自动调整LineHeight以均匀间隔行,并将Padding设置为将文本定位在打印行的正上方
  • 即使文本输入的时间比预期的长,也不允许溢出。 行数以倍数(双倍,然后三倍,依此类推)增加,并且调整了字体大小以尝试在提供的空间中整齐地打印所有内容(例如,没有文本行被打印行划掉)

在实践中,这个作品非常好,导致整齐的形式看,好像有人用旧Selectric做到了手。 唯一的问题是偶然的滚动问题会不时发生。

在Anatoliy提醒我, CanContentScroll尽管启用了内容名称后,它并未启用或禁用内容滚动,而是在按像素滚动和按项目滚动之间切换,但我的问题的含义发生了变化。 但是,我的目的是完全停止TextBox内的滚动行为,并且我现在已经解决了该问题,并且通过消除嵌套的ScrollViewers,还改善了托管它们的ListBox滚动行为:

首先,我找到了此博客文章 ,其中解释了ScrollViewer始终处理MouseWheel 可以将ScrollViewer子类化以防止这种情况,我一直想这样做,直到我想知道为什么我不能不滚动就不能将模板中的内容宿主元素更改为某种内容,因为我根本不需要它。 ContentPresenter不起作用,但是此MSDN页面上重要说明框提到TextBox仅与ScrollViewerAdornerDecorator

切换到AdornerDecorator效果很好:

<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type TextBoxBase}">
            . . .
            <AdornerDecorator x:Name="PART_ContentHost"
                              ClipToBounds="True"
                              Margin="{Binding GetTextOffset}"
                              />
        </ControlTemplate>
    </Setter.Value>
</Setter>

我能够像以前一样将页边距绑定到现有的文本偏移属性以定位文本,并且ClipToBounds将内容限制在可见区域。 另一个主要改进是,现在滚动浏览ListBox框中的这些TextBox的集合现在可以按预期工作,因为文本框不再处理MouseWheel。 嵌套的ScrollViewer令人不快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM