11

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>

ListBox編集: ジョエルの要求に応じて、これを行った理由を追加しました..の内部ScrollViewerが私のレイアウトで行うことが気に入らないため、これを行いました。背景画像があり、その上に次のListBoxように表示されます。

代替テキスト http://robbertdam.nl/share/1.png

スクロールバーが表示されると、次のことが起こります。

代替テキスト http://robbertdam.nl/share/2.png

アイテムのコンテンツのScrollViewerスクロール バーを表示するa のスタイルを作成しました。アイテムのデータ テンプレートで、スクロールバーが表示されるスペースを予約しました。ListBoxListBox

ありがとう、ロバート・ダム

4

4 に答える 4

16

まず、自分の限界と達成しようとしていることを詳しく説明する必要があると思います。それがなければ、あなたがしていることがうまくいかない理由を説明することしかできません。あなたが求めている結果を得る方法について、誰かがより良い考えを持っているかもしれません.

ListBoxの中に入れた場合ScrollViewer、 のコントロール テンプレートにはListBoxまだ独自のScrollViewer内部があります。マウス カーソルが の上にあり、マウスListBoxホイールをスクロールすると、そのイベントがScrollViewerの一部に到達するまでバブル アップしListBoxます。それはスクロールによってそれを処理し、イベントを処理済みとしてマークするので、ScrollViewerイベントListBoxを無視します。

ListBox外側よりも背を高くして狭くしScrollViewer、それ自体が項目をスクロールできるように十分な項目を与えると、ListBox2 つの垂直スクロール バーが表示ListBoxListBoxれますScrollViewer。マウス カーソルが の内側にあるListBox場合、ListBoxはその内部の でアイテムをスクロールし、ScrollViewerそのBorder場所にとどまります。マウス カーソルがアウターのListBox外側と内側にある場合ScrollViewerScrollViewerその内容がスクロールListBoxされます。ListBoxBorder

アウターでコントロール全体 (アイテムだけでなく も含む)ScrollViewerをスクロールする場合は、 のスタイルを変更して internal を持たないようにする必要がありますが、自動的に取得されるようにする必要もあります。アイテムによっては大きくなります。ListBoxBorderListBoxScrollViewer

いくつかの理由から、このアプローチはお勧めしません。ScrollViewer内にと一緒に他のコントロールがある場合は意味があるかもしれListBoxませんが、サンプルはそれを示していません。また、 に多くの項目があるListBox場合は、すべての項目に対して を作成することになり、既定の が原因ListBoxItemで再スタイルされていない既定の利点が失わListBoxれますVirtualizingStackPanel

お客様の実際の要件をお知らせください。


編集: OK、これらの画像を追加することで、もう少し良いアイデアが得られました。あなたが得ている効果は、スクロールするのに十分なアイテムがあり、スクロールバーが表示されると、利用可能な領域が水平方向に少し縮小する必要があるということScrollViewerですGrid. これらは、少ないものから良いものへの順序で、あなたのオプションのようです:

  1. ListBoxを持たないように を再スタイルし、再スタイルした を の外でScrollViewer使用します。また、同じ 内のすべてのアイテムを表示するのに十分な高さを強制する必要があり、UI の仮想化が失われます。リストに何百ものアイテムを表示する場合、それを失いたくはありませんScrollViewerListBoxListBoxStyle
  2. のスタイルを変更し、スクロールバーを別の列ではなくコンテンツの上に配置する、作成済みのスタイルでを使用するようにListBoxを設定します。これは問題ありません (高さを制限し、 を使用するようになります) が、あなたが言ったように、.ControlTemplateScrollViewerListBoxVirtualizingStackPanelDataTemplate
  3. のスタイルを変更して、ScrollViewer表示されていない場合でも垂直スクロール バー用のスペースを残します。このオプションは次のようになります。

デフォルトでは、これに相当するScrollViewer2 つの列を使用します。Grid

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>

したがって、Widthスクロールバーが表示されていない場合、スクロールバーの列の は 0Width="Auto"です。非表示の場合でもスクロールバー用のスペースを残すために、Widthその列の をWidth垂直スクロール バーのにバインドします。

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition
        Width="{Binding ElementName=PART_VerticalScrollBar, Path=Width}" />
</Grid.ColumnDefinitions>

したがってControlTemplate、カスタムStyleの forは次のScrollViewerようになります。

<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スクロールバーが表示されているかどうかにかかわらず、使用する一貫した領域を取得するため、スクロールバーの幅を補正する必要がなくなりました。

の例ControlTemplateScrollViewer残りの部分を確認したくなるでしょうが、これらの例はデフォルトのスタイルではありません。この例では、垂直スクロールバーが左側に配置されていることに注意してください! についての下部のコメントにも注意してくださいContentScrollPresenter

于 2009-08-18T15:52:37.457 に答える
0

マウスのスクロールを機能させたいだけで、ScrollViewer のスタイルが必要ない場合:

  • 外側の ScrollViewer を削除します。
  • ListBox 内にある ScrollViewer の添付プロパティを使用します。

この例の最初の 2 行を参照してください。

<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>
于 2021-02-11T14:03:46.960 に答える