Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. WPF
  4. Adorners and ScrollViewer don't get along

Adorners and ScrollViewer don't get along

Scheduled Pinned Locked Moved WPF
wpfcsharpcsswcfcom
6 Posts 2 Posters 1 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    astibich2
    wrote on last edited by
    #1

    I am using Adorners to show input errors on my textbox controls, and those controls are hosted within a ScrollViewer. For some reason, my adorner UI is clipped when it tries to draw outside the ScrollViewer. I'm not the first to have this problem http://social.msdn.microsoft.com/forums/en-US/wpf/thread/e060205e-5bfc-4f21-bf80-dfa55c44eb8a However, the posted solution does not work for me... Has anyone else run into this problem? Here's the XAML from my example project: <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollViewer}"> <Grid x:Name="Grid" Background="{TemplateBinding Background}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Rectangle x:Name="Corner" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Column="1" Grid.Row="1"/> <AdornerDecorator Grid.Column="0" Grid.Row="0"> <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False"/> </AdornerDecorator> <ScrollBar x:Name="PART_VerticalScrollBar" Cursor="Arrow" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Grid.Column="1" Grid.Row="0" ViewportSize="{TemplateBinding ViewportHeight}" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Value="{Binding Path=VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" AutomationProperties.AutomationId="VerticalScrollBar"/> <ScrollBar x:Name="PART_HorizontalScrollBar" Cursor="Arrow" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Grid.Column="0" Grid.Row="1" Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Value="{Binding Path=HorizontalOffset, Mode=OneWay, Re</x-turndown>

    S 1 Reply Last reply
    0
    • A astibich2

      I am using Adorners to show input errors on my textbox controls, and those controls are hosted within a ScrollViewer. For some reason, my adorner UI is clipped when it tries to draw outside the ScrollViewer. I'm not the first to have this problem http://social.msdn.microsoft.com/forums/en-US/wpf/thread/e060205e-5bfc-4f21-bf80-dfa55c44eb8a However, the posted solution does not work for me... Has anyone else run into this problem? Here's the XAML from my example project: <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type ScrollViewer}"> <Grid x:Name="Grid" Background="{TemplateBinding Background}"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Rectangle x:Name="Corner" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Column="1" Grid.Row="1"/> <AdornerDecorator Grid.Column="0" Grid.Row="0"> <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Margin="{TemplateBinding Padding}" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False"/> </AdornerDecorator> <ScrollBar x:Name="PART_VerticalScrollBar" Cursor="Arrow" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Grid.Column="1" Grid.Row="0" ViewportSize="{TemplateBinding ViewportHeight}" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Value="{Binding Path=VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" AutomationProperties.AutomationId="VerticalScrollBar"/> <ScrollBar x:Name="PART_HorizontalScrollBar" Cursor="Arrow" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Grid.Column="0" Grid.Row="1" Orientation="Horizontal" ViewportSize="{TemplateBinding ViewportWidth}" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Value="{Binding Path=HorizontalOffset, Mode=OneWay, Re</x-turndown>

      S Offline
      S Offline
      SledgeHammer01
      wrote on last edited by
      #2

      Well, yeah, why wouldn't it? You aren't giving it anything bigger to draw on. The ScrollViewer is at the top.

      A 1 Reply Last reply
      0
      • S SledgeHammer01

        Well, yeah, why wouldn't it? You aren't giving it anything bigger to draw on. The ScrollViewer is at the top.

        A Offline
        A Offline
        astibich2
        wrote on last edited by
        #3

        Sorry if I'm not understanding. There is room outside the ScrollViewer for the adorner to draw on. Also, I don't have this problem with any other container type. If I host the textbox inside a Canvas or Grid, the adorner is not clipped and draws outside the container.

        S 1 Reply Last reply
        0
        • A astibich2

          Sorry if I'm not understanding. There is room outside the ScrollViewer for the adorner to draw on. Also, I don't have this problem with any other container type. If I host the textbox inside a Canvas or Grid, the adorner is not clipped and draws outside the container.

          S Offline
          S Offline
          SledgeHammer01
          wrote on last edited by
          #4

          GetAdornerLayer() returns the FIRST AdornerLayer it finds (from the bottom up). HOWEVER (and I neglected to mention this before :), sorry), in some situations it will find one lower then you expect. An AdornerDecorator is one situation, but, tee-hee... a ScrollViewer is another special case :). ScrollContentPresenter is another control that'll stop the adorner layer search. Here is GetAdornerLayer(): public static AdornerLayer GetAdornerLayer(Visual visual) { if (visual == null) { throw new ArgumentNullException("visual"); } for (Visual visual2 = VisualTreeHelper.GetParent(visual) as Visual; visual2 != null; visual2 = VisualTreeHelper.GetParent(visual2) as Visual) { if (visual2 is AdornerDecorator) { return ((AdornerDecorator) visual2).AdornerLayer; } if (visual2 is ScrollContentPresenter) { return ((ScrollContentPresenter) visual2).AdornerLayer; } } return null; } As you can see, it stops once it hits the ScrollContentPresenter :). If you want a larger adorner layer, you'd need to call GetAdornerLayer() on a Visual above the ScrollViewer.

          A 1 Reply Last reply
          0
          • S SledgeHammer01

            GetAdornerLayer() returns the FIRST AdornerLayer it finds (from the bottom up). HOWEVER (and I neglected to mention this before :), sorry), in some situations it will find one lower then you expect. An AdornerDecorator is one situation, but, tee-hee... a ScrollViewer is another special case :). ScrollContentPresenter is another control that'll stop the adorner layer search. Here is GetAdornerLayer(): public static AdornerLayer GetAdornerLayer(Visual visual) { if (visual == null) { throw new ArgumentNullException("visual"); } for (Visual visual2 = VisualTreeHelper.GetParent(visual) as Visual; visual2 != null; visual2 = VisualTreeHelper.GetParent(visual2) as Visual) { if (visual2 is AdornerDecorator) { return ((AdornerDecorator) visual2).AdornerLayer; } if (visual2 is ScrollContentPresenter) { return ((ScrollContentPresenter) visual2).AdornerLayer; } } return null; } As you can see, it stops once it hits the ScrollContentPresenter :). If you want a larger adorner layer, you'd need to call GetAdornerLayer() on a Visual above the ScrollViewer.

            A Offline
            A Offline
            astibich2
            wrote on last edited by
            #5

            You're a genius!! I rewrote the GetAdornerLayer function to be this: public AdornerLayer GetAdornerLayer(Visual visual) { if (visual == null) { throw new ArgumentNullException("visual"); } for (Visual visual2 = VisualTreeHelper.GetParent(visual) as Visual; visual2 != null; visual2 = VisualTreeHelper.GetParent(visual2) as Visual) { if (visual2 is AdornerDecorator) { return ((AdornerDecorator)visual2).AdornerLayer; } //if (visual2 is ScrollContentPresenter) //{ //return ((ScrollContentPresenter)visual2).AdornerLayer; //} } return null; } Works like a charm!! Thanks for your help. Aaron

            S 1 Reply Last reply
            0
            • A astibich2

              You're a genius!! I rewrote the GetAdornerLayer function to be this: public AdornerLayer GetAdornerLayer(Visual visual) { if (visual == null) { throw new ArgumentNullException("visual"); } for (Visual visual2 = VisualTreeHelper.GetParent(visual) as Visual; visual2 != null; visual2 = VisualTreeHelper.GetParent(visual2) as Visual) { if (visual2 is AdornerDecorator) { return ((AdornerDecorator)visual2).AdornerLayer; } //if (visual2 is ScrollContentPresenter) //{ //return ((ScrollContentPresenter)visual2).AdornerLayer; //} } return null; } Works like a charm!! Thanks for your help. Aaron

              S Offline
              S Offline
              SledgeHammer01
              wrote on last edited by
              #6

              Not what I would have done, but whatever works :) You could have just called GetAdornerLayer() on the ScrollViewer instead of the TextBlock.

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups