DataGrid-like scrolling behaviour - wpf

I need to implement control with header and items pane. This control should have scrolling behaviour similar to DataGrid. Header should scroll horizontally along with items, but should be fixed while vertical scrolling. How do I implement such behaviour?

I would use two ScrollViewers, not one
Here's the control layout I would use
<DockPanel>
<ScrollViewer x:Name="HeaderScrollViewer" DockPanel.Dock="Top">
<Grid x:Name="Headers" />
</ScrollViewer>
<ScrollViewer x:Name="ContentScrollViewer">
<Grid x:Name="Content" />
</ScrollViewer>
</DockPanel>
There are a few things to note to make this work correctly.
Hide the ScrollBars on the HeaderScrollViewer. The ScrollViewer is only there for the functionality - the User won't actually interact with it.
When the ContentScrollViewer scrolls horizontally, manually scroll the HeaderScrollViewer the same distance.
Use Grid.IsSharedSizeScope and Grid.SharedSizeGroup to align your header Grid columns with your content Grid columns

Related

Put Horizontal ScrollBar if image width is more than the width of richTextBox

When I add large image (width of the image is larger then width of Rich text Box), it doesn't showed in full size (i.e cropped). I can't scroll it horizontally. How should I enable horizontal scrolling or reduce image size automatically?
You can use a ScrollViewer to add a Scrollbar to any control:
<ScrollViewer ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
<Image Source="/Images/yourImage.png" Stretch="None" />
</ScrollViewer>
UPDATE >>>
You didn't previously say that the image was in a RichTextBox... they have their own ScrollViewers internally, so you can just do this:
<RichTextBox ScrollViewer.HorizontalScrollBarVisibility="Auto" ... />
For future questions, please provide all relevant information with your question.

Scroll position within a ScrollViewer?

I have a form that with a TabControl that contains a number of TabItems. Each of the TabItems contains a ScrollViewer that contains some various contained content.
My problem - if the size of the form and the TabControl and the contained content is such that the ScrollViewer displays its vertical scrollbars, the content is displayed vertically centered within the ScrollViewer. In order to see the top of the content, the user needs to manually scroll to the top.
Oddly enough, when the size is such that the Horizontal scrollbars are displayed, the content is initially aligned to the left, which is what I want.
How do I make these ScrollViewers open with the scrollposition initialized to the top?
<ParentUserControl>
<Grid>
<TabControl>
<TabItem>
<ScrollViewer>
<Grid>
// Assorted Junk
</Grid>
</ScrollViewer>
</TabItem>
<TabItem>
<ScrollViewer>
<ChildUserControl />
</ScrollViewer>
</TabItem>
<TabItem>
<ScrollViewer>
<OtherChildUserControl />
</ScrollViewer>
</TabItem>
</TabControl>
</Grid>
</ParentUserControl>
I think what's happening is the ScrollIntoView event is being fired. This solution worked for me in the past: Stop WPF ScrollViewer automatically scrolling to perceived content

Unable to get vertical scroll bars in an WPF TextBlock

I'm presenting text in a wpf TextBlock control (.Net 3.5). The content of the textblock varies depending on what the user selects in a list box. The text wraps, so I don't need an horizontal scroll bar. However, there is often more text than the amount the window can display, so I need a vertical scroll bar.
As I started searching I quickly found that the answer is to wrap the TextBlock in a ScrollViewer. However, It Does Not Work (TM) and I'm hoping someone can help me work out why.
This is the structure of the UI code:
<Window x:Class=..>
<StackPanel>
<ListBox HorizontalAlignment="Stretch"
VerticalAlignment="Top" Height="200"
SelectionChanged="listbox_changed" SelectionMode="Single">
</ListBox>
<Button Click="Select_clicked">Select</Button>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBlock Name="textblock" TextWrapping="Wrap"/>
</ScrollViewer>
</StackPanel>
</Window>
When the user selects an item in the list box, some text associated with this item is presented in the TextBlock. I would have thought that the code as it stands should have been all that's required, but it never provides me with a scroll bar.
Searching and experimenting have given me two clues: the root of the problem might be related to me updating the content of the TextBlock dynamically, and that the TextBlock does not resize itself based on the new content. I found a posting that seemed relevant that said that by setting the Height of the TextBlock to its ActualHeight (after having changed its content), it would work. But it didn't (I can see no effect of this).
Second, if I set the height (during design time) of the ScrollViewer, then I do get a vertical scroll bar. For instance, if I set it to 300 in the xaml above, the result is almost good in that the window as first opened contains a TextBlock with a vertical scroll bar when (and only when) I need it. But if I make the window larger (resizing it with the mouse during runtime), the ScrollViewer does not exploit the new window size and instead keeps its height as per the xaml which of course won't do.
Hopefully, I've just overlooked something obvious..
Thanks!
Because your ScrollViewer is in a StackPanel it will be given as much vertical space as it needs to display it's content.
You would need to use a parent panel that restricts the vertical space, like DockPanel or Grid.
<DockPanel>
<ListBox DockPanel.Dock="Top" HorizontalAlignment="Stretch"
VerticalAlignment="Top" Height="200"
SelectionChanged="listbox_changed" SelectionMode="Single">
</ListBox>
<Button DockPanel.Dock="Top" Click="Select_clicked">Select</Button>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<TextBlock Name="textblock" TextWrapping="Wrap"/>
</ScrollViewer>
</DockPanel>

WPF Horizontal Scrollbar is not visible

I have a Grid inside ScrollViewer. Grid has only one columns and many rows. I add controls into grid rows. The problem is I can see VerticalScrollBar when I am adding controls but I cannot see HorizontalScrollBar although I add very wide controls.
My xaml looks like the following
<ScrollViewer>
<Grid>
rows ...
</Grid>
</ScrollViewer>
Thanks,
ant.
Set the HorizontalScrollBarVisibility of the ScrollViewer to "Auto" or "Visible".
<ScrollViewer HorizontalScrollBarVisibility="Auto">
<Grid>
... rows ...
</Grid>
</ScrollViewer>

WPF: Trigger a content resize with GridSplitter

I'm trying to force a grid/expander to reevaluate whether it needs a scrollbar, as it's showing emptiness.
I'm using this layout:
<Grid>
<toolstrip /> <!-- fixed height row -->
<Scrollviewer> <!-- * height -->
<Grid> <!-- all rows are 'Auto' height -->
<Expander />
<Expander> <!-- this one stretches far too high -->
<WPF Toolkit: DataGrid />
<Expander>
<GridSplitter/>
<Expander />
<Grid>
</Scrollviewer>
<stackpanel /> <!-- fixed height row -->
<Grid>
The DataGrid (WPF Toolkit) is bound to a property when the Window is initialized. Through some investigating, I've realized that when the window is initialized, the columns in the GridView start at about 10 pixels wide, then the content is added, then they're resized based on the sizes in the XAML (All using star widths - eg: 2*). This causes the grid to resize to about 6 times the height it needs to be as the window is showing, then it doesn't spring back and the only way to see what's at the bottom of the window is to either scroll or move the GridSplitter back up to where it should be and resize the Window. I haven't set the VerticalAlignment properties on anything.
So far I've tried all of the following called InvalidateArrange(), InvalidateVisual();, InvalidateMeasure() and UpdateLayout() on the problem expander and InvalidateArrange(), InvalidateScrollInfo(), InvalidateVisual() and UpdateLayout() on the Grid above it but it won't shrink back.
Is there any way I can force it to short of forcing the width of the columns in the DataGrid?
Try setting these properties on the ScrollViewer:
<ScrollViewer CanContentScroll="True"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Auto">
... content ...
</ScrollViewer>
If that doesn't work, can you provide a more exact representation of your XAML. Also, taking a look at the ScrollViewer in depth may help.

Resources