![](/img/trans.png)
[英]UWP ScrollViewer scrolling work with mouse wheel but not with touch
[英]Putting ListBox in ScrollViewer: mouse wheel does not work
將ListBox
放入ScrollViewer
時,我的鼠標滾輪不起作用。
ListBox
是否以某種方式“竊取”了這個事件?
<ScrollViewer VerticalScrollBarVisibility="Auto" Style="{StaticResource myStyle}">
<ListBox>
<ListBoxItem>Test 1</ListBoxItem>
<ListBoxItem>Test 2</ListBoxItem>
<ListBoxItem>Test 3</ListBoxItem>
<ListBoxItem>Test 4</ListBoxItem>
<ListBoxItem>Test 5</ListBoxItem>
<ListBoxItem>Test 6</ListBoxItem>
<ListBoxItem>Test 7</ListBoxItem>
</ListBox>
</ScrollViewer>
編輯:按照 Joel 的要求,添加了我這樣做的原因。我這樣做是因為我不喜歡ListBox
的內部ScrollViewer
對我的布局所做的事情。 我有一個背景圖片,最上面是一個ListBox
,如下所示:
替代文本 http://robbertdam.nl/share/1.png
現在,當滾動條出現時,會發生以下情況:
替代文本 http://robbertdam.nl/share/2.png
我為ScrollViewer
創建了一個 Style,它在ListBox
項目的內容頂部顯示滾動條。 在ListBox
項的數據模板中,我為滾動條的顯示保留了一些空間。
謝謝,羅伯特大壩
首先,我認為您需要詳細說明您的局限性以及您想要實現的目標。 沒有它,我只能解釋為什么你在做什么不起作用。 有人甚至可能對如何獲得您想要的結果有更好的想法。
如果將ListBox
放在ScrollViewer
中,則ListBox
的控件模板內部仍然有自己的ScrollViewer
。 當鼠標光標位於ListBox
上並且您滾動鼠標滾輪時,該事件會冒泡,直到到達屬於ListBox
的ScrollViewer
為止。 那一個通過滾動來處理它並將事件標記為已處理,因此您將ListBox
放入其中的ScrollViewer
將忽略該事件。
如果您使ListBox
比外部ScrollViewer
更高更窄,並為其提供足夠的項目以便ListBox
本身可以滾動項目,您將看到 2 個垂直滾動條:1 個在ListBox
中,1 個在ListBox
外部用於外部ScrollViewer
。 當鼠標光標位於ListBox
內時, ListBox
將使用其內部的ScrollViewer
項目,並且其Border
將保持原位。 當鼠標光標位於ListBox
外部和外部ScrollViewer
內部時, ScrollViewer
將滾動其內容( ListBox
),您可以通過注意ListBox
的Border
改變位置來驗證這一點。
如果您希望外部ScrollViewer
滾動整個ListBox
控件(包括Border
而不僅僅是項目),您需要重新設置ListBox
的樣式,使其沒有內部ScrollViewer
,但您還需要確保它根據其項目自動變大。
出於幾個原因,我不推薦這種方法。 如果ScrollViewer
中還有其他控件以及ListBox
可能有意義,但您的示例並未表明這一點。 此外,如果ListBox
中有很多項目,您將為每個項目創建ListBoxItem
,從而消除默認的、非重新樣式化的ListBox
由於默認的VirtualizingStackPanel
給您帶來的任何優勢。
請讓我們知道您的實際要求是什么。
編輯:好的,現在我有了一個更好的主意,加上這些圖像。 您得到的效果是,當有足夠多的項目可以滾動並且出現滾動條時,可用區域必須水平縮小一點,因為ScrollViewer
的模板使用了Grid
。 這些似乎是您的選擇,按從小到大的順序排列:
ListBox
的樣式使其沒有ScrollViewer
並在ListBox
外部使用重新設置樣式的ScrollViewer
。 然后您還必須強制ListBox
也足夠高以顯示相同Style
中的每個項目,現在您已經失去了 UI 虛擬化。 如果您要在列表中顯示數百個項目,您絕對不想丟失它。ListBox
的樣式並將ControlTemplate
設置為使用具有您已為其創建的樣式的ScrollViewer
,將滾動條放在內容上方而不是單獨的列中。 這個沒問題( ListBox
開始限制它的高度並使用VirtualizingStackPanel
,是的),但正如你所說,它需要在你的DataTemplate
中意識到這一點。ScrollViewer
的樣式,為垂直滾動條留出空間,即使它不可見。 這是此選項的外觀: 默認情況下, ScrollViewer
在Grid
中使用 2 列,等效於:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
因此,當滾動條從Width="Auto"
開始不可見時,滾動條列的Width
為 0。 為了在隱藏時為滾動條留出空間,我們將該列的Width
綁定到垂直滾動條的Width
:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition
Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>
所以現在ScrollViewer
的自定義Style
中的ControlTemplate
可能如下所示:
<ControlTemplate
TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition
Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<ScrollContentPresenter />
<ScrollBar
Grid.Column="1"
Name="PART_VerticalScrollBar"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
<ScrollBar
Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
</Grid>
</ControlTemplate>
您甚至可以將內容列設置為固定大小,將滾動條列設置為Width="*"
,如果您的圖像未拉伸,從長遠來看,這可能會更好。 現在DataTemplate
不必補償滾動條的寬度,因為無論滾動條是否可見,它都可以使用一致的區域。
您可能想要查看ScrollViewer
的示例ControlTemplate
的其余部分,但這些示例不是默認樣式。 請注意,該示例將垂直滾動條放在左側! 另請注意底部關於ContentScrollPresenter
的評論。
我正在處理同樣的問題。 我設置了ListBox.ItemsPanel屬性,沒有任何ScrollViewer :
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
<ListBox>
<ListBox.Template>
<ControlTemplate TargetType="ItemsControl">
<Border>
<ItemsPresenter />
</Border>
</ControlTemplate>
</ListBox.Template>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<\ListBox>
<\ScrollViewer>
希望這可以幫助。
請參閱此鏈接以獲得另一個答案: 當鼠標懸停在 ListBox 上時在 ScrollViewer 中滾動
您好,我認為您可以處理整個 ListBox 的 PreviewMouseWheel 事件。 只要您不處理每個項目的,這也會影響單個項目
PreviewMouseWheel and mark the event as handled:
private void ListBox_PreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
if (e.Delta < 0)
{
scrollViewer1.LineDown();
}
else
{
scrollViewer1.LineUp();
}
}
如果您只想使鼠標滾動工作並且不需要 ScrollViewer 的樣式:
請參閱此示例的前兩行:
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto">
<ListBoxItem>Test 1</ListBoxItem>
<ListBoxItem>Test 2</ListBoxItem>
<ListBoxItem>Test 3</ListBoxItem>
<ListBoxItem>Test 4</ListBoxItem>
<ListBoxItem>Test 5</ListBoxItem>
<ListBoxItem>Test 6</ListBoxItem>
<ListBoxItem>Test 7</ListBoxItem>
</ListBox>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.