簡體   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