WPF Scrollviewer won't scroll up - wpf

I have the following (simplified) xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="143*" />
<ColumnDefinition Width="135*" />
</Grid.ColumnDefinitions>
<TabControl Margin="12,29" Name="tabControl1" Grid.ColumnSpan="2">
<TabItem Header="TabItem1" Name="tabItem1">
<ScrollViewer Height="440" Name="scrollViewer1" Width="872" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid Height="440" Name="grid1" Width="851" VerticalAlignment="Top" HorizontalAlignment="Left">
...
My problem is the scroll won't show up. What should I change ?
Thanks.

The content inside the ScrollViewer is smaller than the ScrollViewer itself. The ScrollViewer is used for being able to use scrollbars to show content that is larger than the area the ScrollViewer takes up.

Related

Stretch WPF Dockpanel contents horizontally

I have a DockPanel and it contains a ScrollViewer [ center aligned ] and a button on left and right .
My xaml is like
<DockPanel LastChildFill="True">
<Button VerticalAlignment="Stretch" HorizontalAlignment="Stretch" DockPanel.Dock="Left">Left</Button>
<Button VerticalAlignment="Stretch" HorizontalAlignment="Stretch" DockPanel.Dock="Right">Right</Button>
<ScrollViewer Name="scrollAreaPageView" HorizontalAlignment="Center" VerticalAlignment="Center"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
</ScrollViewer>
</DockPanel>
And it generates the output as expected , but Left and right butons are not stretched fully to left and right to the ScrollViewer( They are on corners only).
The screen shot of output is
How can i make it stretch fully to left and right of center scrollViewer
A DockPanel may not be ideal in this scenario you may perhaps use Grid here with the desired column definition
sample
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button>Left</Button>
<ScrollViewer Name="scrollAreaPageView"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Grid.Column="1">
</ScrollViewer>
<Button Grid.Column="2">Right</Button>
</Grid>
in above example the space available after subtracting the space required b
Alternate approach
I attempted to do it pure xaml, this approach will helo you achieve the desired without code behind. here is the example
<Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="{Binding ActualWidth,ElementName=scrollAreaPageView}" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button>Left</Button>
<Button Grid.Column="2">Right</Button>
</Grid>
<ScrollViewer HorizontalAlignment="Center"
VerticalAlignment="Center"
Margin="50,0"
Name="scrollAreaPageView"
HorizontalScrollBarVisibility="Auto">
</ScrollViewer>
</Grid>
Margin in the scrollAreaPageView element defines minimum width of the buttons. give it a try and see if that helps

Set height and width of controls wihtin window size wpf

I have a following xaml file
<Window x:Class="NodeXL_Graph_Drawer.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:toolkit="http://schemas.microsoft.com/wpf/2008/toolkit"
xmlns:controls="clr-namespace:Technewlogic.Samples.WpfModalDialog"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="NodeXL Graph" xmlns:my="clr-namespace:Smrf.NodeXL.Visualization.Wpf;assembly=Smrf.NodeXL.Control.Wpf" Loaded="Window_Loaded">
<Grid>
<Grid x:Name="ModalDialogParent" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" x:Name="col1"/>
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" >
<my:NodeXLControl Name="nodeXLControl1" HorizontalAlignment="Left" EdgeSelectedColor="Red" VertexSelectedColor="Red" ShowVertexToolTips="True" VertexClick="nodeXLControl1_VertexClick" SelectionChanged="nodeXLControl1_SelectionChanged" MouseMode="Select" MouseAlsoSelectsIncidentEdges="False" ContextMenuOpening="nodeXLControl1_ContextMenuOpening" GraphLaidOut="nodeXLControl1_GraphLaidOut">
</my:NodeXLControl>
</StackPanel>
<!--<ComboBox Height="23" Margin="39,12,119,0" Name="comboBox1" VerticalAlignment="Top" SelectionChanged="comboBox1_SelectionChanged" />-->
<GridSplitter Grid.Column="1" HorizontalAlignment="Stretch"/>
<StackPanel Grid.Column="2">
<toolkit:DataGrid AutoGenerateColumns="True" Margin="0,62,0,0" Name="grdGraphDetails" ItemsSource="{Binding GraphDetail}" IsReadOnly="True"
HorizontalAlignment="Right" Width="109" MouseLeftButtonUp="grdGraphDetails_MouseLeftButtonUp"
SelectedValuePath="Key" Height="179" />
</StackPanel>
</Grid>
<controls:ModalDialog x:Name="ModalDialog"></controls:ModalDialog>
<controls:ModalDialog1 x:Name="ModalDialog1"></controls:ModalDialog1>
</Grid>
Here i have two controls NodeXlControl1 and Datagrid1 on page seprated by grid seprator. when window loads NodeXlControl1 does not come within the grid column width and height. i want nodexlcontrol1 should be shown with in the grid column width and height. and i if it goes beyond the limits of width and height of column, scroll bar should come.
If your my:NodeXLControl internally has some scroll viewer (like some ItemsControl or ScrollViewer based child) then simply wrapping my:NodeXLControl in a Grid would do the trick.
StackPanel expands to overflow the children. Grid expands to outer's container's availability of space.
<Grid>
<my:NodeXLControl ... />
Should do the trick.
But if you my:NodeXLControl has no scroll viewer in it then you would need to wrap it inside one and provide absolute width or height to it or wrap it inside a Grid for it to bound to its avilable space and show scrollbars accordingly.
e.g.
<Grid>
<ScrollViewer ...>
<my:NodeXLControl ...>

Silverlight: GridSplitter inside ScrollViewer behaving unexpectedly

I'm trying to build a two-column layout where the width of the columns can be changed by using a splitter. The right column's width shouldn't change when the browser window is resized (it shouldn't be proportional to the grid width). Both columns should have a minimum width. When the browser window is too narrow to display both columns a scrollbar should appear.
This is my XAML:
<Grid x:Name="LayoutRoot" Background="White">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<Grid Height="200" Margin="0,0,0,0" MinWidth="400" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="300" Width="300*" />
<ColumnDefinition Width="10" />
<ColumnDefinition MinWidth="100" Width="100"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="Red" x:Name="LeftColumn"></Grid>
<sdk:GridSplitter Grid.Column="1" HorizontalAlignment="Center" Width="10" Background="Black" />
<Grid Grid.Column="2" Background="Green" x:Name="RightColumn"></Grid>
</Grid>
</ScrollViewer>
</Grid>
The problem I'm having is when the splitter is dragged to the left and the left column's minwidth is reached - the right column begins to grow very rapidly and the scrollbar appears. Removing the width setting from the right column eliminates the weird behavior but now the right column starts to grow proportionally when the window is resized...
I'd like the splitter to behave the same way as when it is dragged to the right - I'd like it to stop after the minwidth is reached.
You should disable the "HorizontalScrollBarVisibility".
This code works for me:
<Grid x:Name="LayoutRoot" Background="White">
<ScrollViewer HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Disabled">
<Grid Height="200" Margin="0,0,0,0" MinWidth="400" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="300" Width="300*" />
<ColumnDefinition Width="10" />
<ColumnDefinition MinWidth="100" Width="100"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="Red" x:Name="LeftColumn"></Grid>
<sdk:GridSplitter Grid.Column="1" HorizontalAlignment="Center" Width="10" Background="Black" />
<Grid Grid.Column="2" Background="Green" x:Name="RightColumn"></Grid>
</Grid>
</ScrollViewer>
</Grid>
The ScrollViewer gives the grid endless space to grow. Hence the minWidth never stops it.
Obviously there is no need of ScrollViewer that is disabled both vertically and horizontally. Better move the scroll bar inside the grid surrounding the content of every column.
I think I was finally able to come up with a workaround. I'm forcing the width in the code-behind when the layout is changing.
XAML:
<Grid x:Name="LayoutRoot" Background="White">
<ScrollViewer x:Name="Scroller" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<Grid x:Name="Workspace" Height="200" Margin="0,0,0,0" MinWidth="400" VerticalAlignment="Top" LayoutUpdated="Workspace_LayoutUpdated">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="300" Width="300*" />
<ColumnDefinition Width="10" />
<ColumnDefinition MinWidth="100" Width="100"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="Red" x:Name="LeftColumn"></Grid>
<sdk:GridSplitter Grid.Column="1" HorizontalAlignment="Center" Width="10" Background="Black" />
<Grid Grid.Column="2" Background="Green" x:Name="RightColumn"></Grid>
</Grid>
</ScrollViewer>
</Grid>
Code behind:
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
}
private void Workspace_LayoutUpdated(object sender, EventArgs e)
{
Workspace.Width = Scroller.ViewportWidth - 1;
}
}
The reason it behaves this way is that you have specified the first column Width="300*" with asterisks,
and the third column Width="100" without asterisks.
Just put asterisks to the first and third columns, or remove respectively, and it will work the way you wish.

WPF Layout Control

I am new to WPF.
I have a wpf window which contains a grid which is dynamic in size along with its columns. This window is supposed to be a small utility type window that is always ontop.
The issue is as the user types into the richtextbox it expands of the bottom of the page, I would like a scroll bar to appear.
I have tried placing it in a container but this doesnt work.
I want the grid to resize if the user decides to resize the window.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="202" Width="927" WindowStyle="ToolWindow" ShowInTaskbar="True" Topmost="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<GridSplitter HorizontalAlignment="Right"
VerticalAlignment="Stretch"
ResizeBehavior="PreviousAndNext"
Grid.Column="1"
Width="1"
ResizeDirection="Columns"/>
<GridSplitter HorizontalAlignment="Right"
ResizeBehavior="PreviousAndNext"
VerticalAlignment="Stretch"
Grid.Column="3"
Width="1"
ResizeDirection="Columns"/>
<StackPanel Grid.Column="2" Height="Auto">
<Label Background="SteelBlue" HorizontalAlignment="Stretch" Foreground="white" Height="25">Note</Label>
<RichTextBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" >
</RichTextBox>
</StackPanel>
</Grid>
</Window>
Have you tried:
<RichTextBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
***Height="300">***
</RichTextBox>
StackPanels do not do vertical layout, you should probably either use a DockPanel or a Grid with two Rows instead, that way the RichTextBox is bounded and knows when to use its scrolling functionality.
Thank H.B replacing StackPanel with grid worked. Alex adding the height didnt work sorry.
So I replace the StackPanel with
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="25"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Background="SteelBlue" HorizontalAlignment="Stretch" Foreground="white" Height="25">Note</Label>
<RichTextBox ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Row="1">
</RichTextBox>
</Grid>

WPF Element Binding With Dynamically Generated UI Elements

I have a page in which I have a grid with 2 columns, one accommodating 80* width and the other accommodating 20*. Beneath the grid is a stack panel to which I load UI elements (child stack panels) at runtime.
My objective is to bind the widths of the stackpanels to the columns of the grid. This works perfectly and the stackpenels resize if the dynamic content is mocked to be static in the design view. But when the application is run, the bindings fail and the widths are not bound.
Is there any way to refresh the bindings so that I can notify the stackpanels to refer the widths of the grid and configure its's size?
Updated:
This is what my XAML looks like:
<Page x:Class="WPFTestApp.Page1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Page1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="resizeGrid"
Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftColumn"
Width="80*" />
<ColumnDefinition x:Name="rightColumn"
Width="20*" />
</Grid.ColumnDefinitions>
</Grid>
<StackPanel x:Name="contentPanel"
Grid.Column="0" Grid.Row="0" >
<!-- Dynamic StackPanels are added here -->
</StackPanel>
</Grid>
</Page>
In my code, I create StackPanel elements and add it to the contentPanel by saying:
contentPanel.Children.Add(...);
Unfortunately, I HAVE to use StackPanels here. :-(
The markup of a dynamically created StackPanel element is as follows (note that I use a Binding to the grid already in the XAML):
<StackPanel x:Name="element01"
Orientation="Horizontal"
Width="{Binding ElementName=resizeGrid, Path=ActualWidth}" >
<StackPanel x:Name="leftPanel"
Orientation="Vertical"
Width="{Binding ElementName=leftColumn, Path=ActualWidth}">
<!-- Content goes here -->
</StackPanel>
<StackPanel x:Name="rightPanel"
Orientation="Vertical"
Width="{Binding ElementName=rightColumn, Path=ActualWidth}">
<!-- Content goes here -->
</StackPanel>
</StackPanel>
The XAML code for my dynamic StackPanel elements are generated through an XSLT transformation
Note the xmlns:x namespace dynamic StackPanel. This also has to be done because of it being generated through XSLT
As far as I know setting the Width of a StackPanel with Orientation="Horizontal" will have no effect. The size of a StackPanel does not exceed the size of its content in its oriented direction.
Why do you "HAVE" to use StackPanels here? You almost certainly want DockPanels, given your objective. You won't have to bind or set anything, because the DockPanel will fill the cell automatically.
Try binding the ActualWidth instead of Width.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="resizeGrid"
Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="leftColumn"
Width="{Binding ElementName=contentPanel, Path=ActualWidth}" />
<ColumnDefinition x:Name="rightColumn"
Width="*" />
</Grid.ColumnDefinitions>
</Grid>
<StackPanel x:Name="contentPanel"
Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" >
<StackPanel Background="Yellow" Width="100" Height="25" />
<StackPanel Background="Green" Width="120" Height="25" />
<StackPanel Background="Red" Width="140" Height="25" />
<TextBlock Background="Gray" Text="{Binding ElementName=contentPanel, Path=ActualWidth}" />
</StackPanel>
</Grid>
The following changes I have done above:
1) Set the leftColumn to the ActualWidth of the contentPanel
2) Set the rightColumn to *
3) contentPanel HorizontalAlignment should be changed other then Stretch. Here I have changed it to Left
HTH
I found a solution for this issue. (Sorry for the late response)
What I did was, I cut and pasted the "resizeGrid" Grid control into the "contentPanel" Stackpanel.
As I mentioned above, the contents within the contentPanel are generated through an XSLT transformation and this surely creates a namespace reference issue. I noticed "element not found..." message in the Output window whenever this Window is loaded - this proved me right.
Inserting the "resizeGrid" into the "contentPanel" helped because then both the controls are within the same namespace and can be referenced for a PropertyBinding using "ElementName" attribute.
Thank you for your support! :-)

Resources