My app has a resizable WPF window with a frame which shows different WPF pages. Most of the time the pages are bigger than the frame and if this is the case, the frame should display scrollbar(s). Unfortunately, it never shows any scrollbar.
Here is my code:
<Grid>
<Frame Name="MainFrame"
NavigationUIVisibility="Hidden"
Width="Auto"
Height="Auto"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
</Grid>
Code behind:
MainFrame.Navigate(new Page1());
What did I do wrong?
Try wrapping your Frame in a ScrollViewer:
<Grid>
<ScrollViewer>
<Frame Name="MainFrame"
NavigationUIVisibility="Hidden"
Width="Auto"
Height="Auto"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto" />
</ScrollViewer>
</Grid>
I had the same problem and I gave up and just set the Visibility to Visible. If it did not need the scrollbar then no real harm done.
Had the same problem, nothing worked. So I’ve used a workaround to solve it by adding scrollviewer to the target page
and setting page size to frame size
<Page x:Class="PageInFrame" Height="1050" Width="555" > …
<ScrollViewer x:Name="svScroll" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid x:Name="LayoutRoot" Height="1050" Width="555">
…..
</Grid>
</ScrollViewer>
Set/Replace page Height and Width property to target/containing frame size (can be done runtime or design time)
Related
Following XAML code:
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<DockPanel LastChildFill="True">
<TextBox Name="textBox1" DockPanel.Dock="Top" />
<GroupBox Header="All Events" DockPanel.Dock="Top">
<RichTextBox Margin="5" Name="richTextBoxEvents"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto" />
</GroupBox>
</DockPanel>
</ScrollViewer>
causes everything displayed in the RichTextBox vertically!
I want the text to appear horizontally. Why is this appearing vertically and how can I fix that?
I'm using C#, WPF and .NET 4.
EDIT
If the ScrollViewer is taken away, then the text appear horizontally. But I need the scroll viewer. What's the solution then?
A similar scenario can be found here.
Your problem can be solved by setting the width of the RichTextBox.
By setting some arbitrary width.
<RichTextBox Margin="5" Name="richTextBoxEvents"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Width="100" />
Or you can assign the width of the Parent.
<RichTextBox Margin="5" Name="richTextBoxEvents"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Width="{Binding RelativeSource={RelativeSource FindAncestor,
AncestorType=Window, AncestorLevel=3}, Path=ActualWidth}" />
Here you can change the ancestor level depending on your needs,I bind the RichTextBox width to the Window's width and AncestorLevel is 3.
RichTextBox will always word wrap, so I'm assuming that the ScrollViewer is forcing it to start word wrapping.
If you remove the auto visibility, then it works as expected and you'll still get your scrollbars:
<ScrollViewer>
<DockPanel LastChildFill="True">
<TextBox Name="textBox1" DockPanel.Dock="Top" />
<GroupBox Header="All Events" DockPanel.Dock="Top">
<RichTextBox Margin="5" Name="richTextBoxEvents" />
</GroupBox>
</DockPanel>
</ScrollViewer>
NOTE: This is one of the first time I'm using WPF.
I am trying to align a certain control, let's say a button for now, in the bottom right corner. But when I debug my application, it misses 8 pixels to the bottom and right. I will attach 2 pictures to show you what happens.
How do I keep the button in place?
My XAML code:
<Window x:Class="Plugin_Manager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Plugin Manager" Height="350" Width="525" Loaded="Window_Loaded_1">
<Grid x:Name="GridMain">
<Button Content="Refresh" Margin="432,288,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="75"/>
<ListView HorizontalAlignment="Left" Height="273" Margin="10,10,0,0" VerticalAlignment="Top" Width="497">
<ListView.View>
<GridView>
<GridViewColumn/>
</GridView>
</ListView.View>
</ListView>
</Grid>
If you choose to use Grid layout you should try to avoid placing objects via Margin. Margin should be used to create buffer around an object, not move it to a specific point in the window. Use the layout manager's power to your advantage!
Here is a Grid example that does what you are looking for.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ListView Grid.Row="0" />
<Button Grid.Row="1" HorizontalAlignment="Right" Content="Push Me" />
</Grid>
I would also read up on Layout Manager in WPF. There are several; each having its own advantages & disadvantages.
Here is a DockPanel version.
<DockPanel>
<Button DockPanel.Dock="Bottom" HorizontalAlignment="Right" Content="Push Me" />
<ListView />
</DockPanel>
To create your buffer between the button and the window chrome you could do a few different things:
<Grid Margin="10"> will apply a 10 pixel space between all content and the window chrome on all side.
<Grid Margin="0,0,10,10"> would indent all content, but only on the right & bottom.
<Grid Margin="10,0,10,10"> indents all around, except the top (I commonly do this one, with a different margin value).
<Button Margin="0,0,10,10"> would indent only the button from the chrome (this is the direct answer to your comment question).
Replace the Grid above with DockPanel for the second example, or whatever other Layout Manager you are using.
A usability side note: Your confirmation buttons (I'm assuming your button will be an Ok/Cancel type button) should not be indented differently from the rest of your content. All controls that butt up against the right margin should do so at the same point (i.e., you can draw a vertical line down the right side of them all).
So, using your question's example: your button should not be indented 10 pixels to the right while your list box is not. Keeping things lined up will improve the overall look to your application.
(this ends my "usability and look-and-feel is important" side note) :)
<Button VerticalAlignment="Bottom" HorizontalAlignment="Right" Margin="5"/>
Some code example will help. Try using the alignment in xaml for your button as shown below. Ensure that the margins on the button are 0.
<Button Margin="0" HorizontalAlignment="Right" VerticalAlignment="Bottom"/>
Looking at the sample code, it is your margins and the alignment you have that are probably causing that.
Just some pointers that may help. Instead of using large margins to align the controls, I find it much easier to work with Column and Row definitions on the grid. This way you can align your controls using the grid and they will size properly as you resize your window. I attached an example in hopes it helps in your new adventures with WPF!
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Text="Version Date" Margin="3" VerticalAlignment="Center"/>
<TextBlock Grid.Column="0" Grid.Row="1" Text="{Binding DateSubmitted}" Margin="3"/>
<TextBlock Grid.Column="1" Grid.Row="0" Text="Report" Margin="3" VerticalAlignment="Center"/>
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding ReportName}" Margin="3"/>
</Grid>
I am designing a visual studio extension in which I need a dock panel window. I am able to get this window using WPF. In this particular window I am displaying dynamic list of some strings which exceeds 100. To achieve this, I am using listbox in that window.
As this list contains more than 100 strings, all the strings are not visible. I should be able scroll the list vertically to access all the strings. But I am not getting a vertical scrollbar. I tried some things but they are not working. I am a newbie to this so, I am unable to figure out what to do. The code is as follows.
<UserControl d:DesignHeight="300" d:DesignWidth="300">
<Grid >
<StackPanel Orientation="Vertical" CanVerticallyScroll="True" CanHorizontallyScroll="True" >
<TextBlock Margin="10" HorizontalAlignment="Center" Foreground="{DynamicResource {x:Static vsfx:VsBrushes.ToolWindowTextKey}}" Text="Available Projects"></TextBlock>
<ListBox Name="AllProjects" TabIndex="0" Height="Auto" ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Visible" />
</StackPanel>
</Grid> </UserControl>
I did these things in xaml form only and nothing in back-end c# code. Could you guys please tell me where I am going wrong?
Use this you will see the scrollbar
<Grid >
<StackPanel Orientation="Vertical" CanVerticallyScroll="True" CanHorizontallyScroll="True" >
<TextBlock Margin="10" HorizontalAlignment="Center" Text="Available Projects"></TextBlock>
<ListBox Name="AllProjects" TabIndex="0" ScrollViewer.VerticalScrollBarVisibility="Visible" Height="100" />
</StackPanel>
</Grid>
Just fix the height property to a constant.
I have the layout code below in xaml
<Grid>
<StackPanel x:Name="TestStackPanel" Grid.Row="2" Orientation="Horizontal">
<ScrollViewer x:Name="TestScrollViewer" Height="300" VerticalScrollBarVisibility="Auto">
<GridView x:Name="TestGridView"
Width="940"
Background="{StaticResource ApplicationPageBackgroundThemeBrush}"
ItemTemplate="{StaticResource TestTemplate}"
ItemsPanel="{StaticResource TestItemPanelTemplate}"
ItemContainerStyle="{StaticResource TestItemStyle}"
SelectionMode="None"
HorizontalAlignment="Left"/>
</ScrollViewer>
<Button x:Name="TestButton" Content="ClickMe" VerticalAlignment="Bottom" Margin="10,5,0,0" Click="TestButton_Click"/>
</StackPanel>
</Grid>
This displays well in 1366*768 resolution, but if I change the resolution to 2560*1400, it couldn't displays as expected, I know it's certain, but how to adpat the layout to different resolutions? I have tried to add a ViewBox to encapsulate the Grid, it works well in FullScreenLandScape view, but when I change the app to Snap view, the Grid displays in a samll space.
Anyone can help?
Register to the LayoutUpdated event at the UI element.
And re-calculate the layout according to Window.Current.Bounds.Width.
Everything about my layout will flow with the resizing of the main window. The problem I'm facing is that as you can see, the datagrid goes off the screen. If you maximize the window, the datagrid will resize with the window, but continue to go off the screen. How do I get it to maintain its margin of 20 with it's parent grid?
<Grid>
<StackPanel Orientation="Vertical">
<TextBox Height="170" Name="txtSQL" VerticalAlignment="Top" AcceptsReturn="True" TextWrapping="Wrap" Margin="20"/>
<Button Content="Run!" Height="23" HorizontalAlignment="Left" Name="btnRun" VerticalAlignment="Top" Margin="20,0,0,0" Width="75" Click="btnRun_Click" />
<Grid>
<my:DataGrid Name="dgResults" VerticalAlignment="Top" Margin="20" />
</Grid>
</StackPanel>
</Grid>
UPDATE:
Just to be more specific. The effect I'm trying to accomplish here is this:
When the window first loads, you are presented with a blank datagrid, so it's only about 15 pixels high. When you run the query, it will populate the datagrid by reassigning the itemssource. As of now, when you do that, if the data exceeds the window size, it will go off the bottom of the screen. I need it to only expand to the bottom of the window then enable the scrollbar. I can do this just by wrapping it in a scrollviewer im sure. However, when the window is resized, the datagrid needs to resize with it.
I'm wondering if the setup might have something to do with it. The form is actually a wpf page being displayed in a frame.
UPDATE:
<Page x:Class="Hold_Database___Prototype_1.Views.SQL"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="304" d:DesignWidth="732"
Title="SQL" xmlns:my="http://schemas.microsoft.com/wpf/2008/toolkit" AllowDrop="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="23" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Height="170" Name="txtSQL" VerticalAlignment="Top" AcceptsReturn="True" TextWrapping="Wrap" Margin="20" Grid.Row="0"/>
<Button Content="Run!" Height="23" HorizontalAlignment="Left" Name="btnRun" VerticalAlignment="Top"
Margin="20,0,0,0" Width="75" Grid.Row="1" Click="btnRun_Click" />
<DockPanel Grid.Row="2">
<my:DataGrid Name="dgResults" Margin="20" />
</DockPanel>
</Grid>
</Page>
What is the dock panel for in this example?
Try putting the DataGrid directly in the cell with no stackpanel. If you are setting the button height then set set grid to auto.
Also, why give so much space to the text?
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBox Height="170" Name="txtSQL" VerticalAlignment="Top" AcceptsReturn="True" TextWrapping="Wrap" Margin="20" Grid.Row="0"/>
<Button Content="Run!" Height="23" HorizontalAlignment="Left" Name="btnRun" VerticalAlignment="Top"
Margin="20,0,0,0" Width="75" Grid.Row="1" Click="btnRun_Click" />
<my:DataGrid Grid.Row="2" <my:DataGrid Name="dgResults" Margin="20" />
Then also set HorizontalAlignment, VerticleAlignment, HorizontalContentAlignment, and VerticalContentAlignment = stretch
Your Grid is drawn off screen without a scroll bar because you are using a StackPanel. Care must be taken when using StackPanel - it is the most simplistic of all WPF Panel derived classes since its MeasureOverride calls Measure for all of its children with a size of double.PositiveInifity regardless of how much space the panel actually has available. Even a ScrollViewer will not help you with a StackPanel (the ScrollBar will be shown, but you won't be able to move it).
For example, consider a Window 350 in height and width, and a single Button as its content which is 500 in both height and width:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="350">
<StackPanel>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Button Content="Hello" Height="500" Width="500" />
</ScrollViewer>
</StackPanel>
</Window>
Similar to your example, the Button here is drawn off screen in both the vertical and horizontal directions and a non-functional scroll bar will be present. If we change the panel to one which respects the size of its given area (e.g. DockPanel):
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<DockPanel>
<ScrollViewer>
<Button Content="Hello" Height="500" />
</ScrollViewer>
</DockPanel>
</Window>
then scroll bars appear which are functional and hence allow the content off screen to be shown by scrolling.
Hope this helps!
What I have done was do define the horizontal and vertical alignments to "Stretch" respectively at the control you want (your DataGrid) to take up the size based on the window being resized.