Making vertical nested scroll always visible - c#

I have the following Xaml. I have a grid containing some "columnheaders" and a list box. Currently my horizontal scroll bar scroll both the column headers and the listbox. My vertical scroll bar only scrolls the listbox as I want the column header "frozen". The issue I have is that I have to scroll all the way to the right to see the vertical scroll bar. Is there anyway of "locking" the vertical scroll bar to be always visible ( when its required ) and for it to only scroll the listbox? Please let me know if you need anymore information.
<Grid Name="test1" Margin="0,0,50,0" Grid.Row="0">
<ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Auto" Width="{Binding ElementName=test1, Path=ActualWidth}">
<Grid Name="grdMain" >
<Grid.RowDefinitions>
<RowDefinition Height="10*" />
<RowDefinition Height="90*" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<ItemsControl Name="ColumnHeaders" ..>
</ItemsControl>
</StackPanel>
<StackPanel Name="check" Grid.Row="1">
<ScrollViewer Height="{Binding ElementName=check, Path=ActualHeight}" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Hidden">
<ListBox Name="lstDrop" ..>
</ListBox>
</ScrollViewer>
</StackPanel>
</Grid>
</ScrollViewer>
</Grid>
Here are screen shots of current functionality:

Finally, it was a bit nastier as I thought. Nevertheless, here is some stuff. I had to do some changes on the initial idea and your layout, but afterwards it'll look all the same.
<Grid Name="test1" Margin="0,0,50,0" Grid.Row="0">
<Grid Name="grdMain" >
<Grid.RowDefinitions>
<RowDefinition Height="10*" />
<RowDefinition Height="90*" />
</Grid.RowDefinitions>
<ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden" Name="scv_headers">
<ItemsControl Name="ColumnHeaders">
<!--Headers here-->
</ItemsControl>
</ScrollViewer>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Visible" ScrollChanged="List_OnScrollChanged">
<ListBox Name="lstDrop">
<!--Items here-->
</ListBox>
</ScrollViewer>
</Grid>
</Grid>
Because the scrollbars are hidden in the template, I had to add some code behind
private void List_OnScrollChanged(object sender, ScrollChangedEventArgs e)
{
var scrollbarSrc = (ScrollBar)((ScrollViewer)e.OriginalSource).Template.FindName("PART_HorizontalScrollBar", (ScrollViewer)e.OriginalSource);
scv_headers.ScrollToHorizontalOffset(scrollbarSrc.Value);
}
Because your stackpanels only contain one item, I left them away which looks pretty much the same.

Related

WPF Listbox stretching issues

I have created a UserControl that is suppose to display some text and then present a listbox for the user to select some item.
It is supposed to strech to the height to the grid cell it is placed in. And if there are more items than can fit on screen then to display a vertical scrollbar. After much trial and error I have finally managed to get it working as expected. But only when the row height is a pixel value. If I use any partial (by partial I mean the star symbol), the grid cell's height is not contained. Since I need the app the match screen size I need the partials to work.
Putting 100 items in the listbox suddenly makes the height of the entire grid is around 11000 (which I think is everything with no contraint). Meaning there is no scrollbar. See [Screenshot] https://i.stack.imgur.com/faES9.png.
I have a similar issue with my TextBox only horizontally. It will only activate when clicking on a specific pixel since it is empty the width is only 1 pixel. I hope someone can help me point out where I am going wrong, cause since I'm having more than one issue I suspect the problem is on my end.
This is my XAML code.
<UserControl x:Class="PackingStation.UserControls.SearchItemListing"
x:Name="SearchItemListingRoot"
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"
xmlns:local="clr-namespace:PackingStation.UserControls"
mc:Ignorable="d"
d:DesignHeight="1000" d:DesignWidth="1000">
<Grid DataContext="{Binding ElementName=SearchItemListingRoot}"
x:Name="TheGrid"
VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height=".1*" />
<RowDefinition Height=".1*" />
<!-- If this value isnt a pixel value it will not vertically strech to available space -->
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel HorizontalAlignment="Center"
Margin="0,0,0,0"
x:Name="TheHeadLineField"
Grid.Row="0"
Grid.Column="1">
<Label Style="{StaticResource LabelStyleHeadline32}"
Content="{Binding Title}"
HorizontalAlignment="Left"/>
<Label Style="{StaticResource LabelStyleText}"
HorizontalAlignment="Left"
Content="{Binding SubTitle}"
FontSize="20"/>
</StackPanel>
<!-- Search Field -->
<Border Style="{StaticResource Border6}"
x:Name="TheSearchField"
Grid.Row="1"
Grid.Column="1"
Background="{StaticResource ColorSummaryPanelBackground}"
BorderBrush="{StaticResource ColorSummaryPanelBorder}"
BorderThickness="1"
Margin="0,40,0,0">
<StackPanel Orientation="Horizontal"
Height="78"
HorizontalAlignment="Stretch">
<Image Stretch="Uniform"
Height="24"
Source="pack://application:,,,/WpfUI;component/Icons/Search.png"
Margin="36,0,0,0"
VerticalAlignment="Center"/>
<!-- Search Textbox -->
<!-- Similar issue with this textbox, only horizontally. With no content you have to hit a specific pixel to activate it -->
<TextBox Style="{StaticResource TextBoxSearchInlay}"
Name="TbxSearchTerm"
TextChanged="TextBoxBase_OnTextChanged"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"
Margin="20,0,0,0"/>
</StackPanel>
</Border>
<!-- Search results listings -->
<ListBox ItemsSource="{Binding Items}"
x:Name="TheListBox"
Grid.Row="2"
Grid.Column="1"
SelectedItem="{Binding SelectedItem, Mode=TwoWay}"
ScrollViewer.VerticalScrollBarVisibility="Auto"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch" Margin="0,-10,0,-10">
<Label Style="{StaticResource LabelSearchItem}"
Content="{Binding Name}"
HorizontalContentAlignment="Stretch"
HorizontalAlignment="Stretch"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</UserControl>
I could repro your problem when I put your UserControl in a StackPanel. When it's in a Grid the ListBox shows its vertical scrollbar. So, try your UserControl in a Grid.
I think this answer will give a good explanation about Grid and StackPanel stretching behavior.

In WPF, TreeView is having a different outline shadowing that StackPanel with border. How to fix that?

I have a window with a TreeView with a BorderThickness of 1 and a StackPanel inside a Border element with a BorderThickness of 1.
As you can see in the following picture, the Border gets a shadowing effect but the Treeview doesn't. How to fix this (if possible remove the shadow effect)?
general view
zoom view
I tried setting BorderThickness of TreeView to 0 and put TreeView in a Border , but it didn't work.
XAML summary:
<Grid Name="MainGrid" Margin="5,5,5,5">
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<TreeView ItemsSource="{Binding FinalResult}"
SelectedItemChanged="TreeView_SelectedItemChanged"
BorderThickness="1"
>
<TreeView.Resources>
</TreeView.Resources>
</TreeView>
<GridSplitter Grid.Column="1" Width="5" HorizontalAlignment="Stretch" />
<Border BorderBrush="#ff828790" BorderThickness="1" Grid.Column="2">
<StackPanel>
</StackPanel>
</Border>
</Grid>
I think that you might benefit from using the UIElement.SnapsToDevicePixels Property. From the linked page:
Gets or sets a value that determines whether rendering for this element should use device-specific pixel settings during rendering.
If you set this property to true on your blurry control, it should align it directly with the actual pixels to remove the blurriness:
<Border BorderBrush="#ff828790" BorderThickness="1" Grid.Column="2"
SnapsToDevicePixels="True">
...
</Border>

How to make controls fill the container in WPF?

Below is my xaml code :
<Window x:Class="ScoresBank.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow">
<DockPanel LastChildFill="True">
<WrapPanel DockPanel.Dock="Top">
<ToolBar Height="25"></ToolBar>
</WrapPanel>
<WrapPanel DockPanel.Dock="Bottom">
<StatusBar Name="stbBottom" Height="25"
BorderThickness="2"
BorderBrush="Black">Example</StatusBar>
</WrapPanel>
<StackPanel DockPanel.Dock="Left">
<DockPanel LastChildFill="True">
<WrapPanel DockPanel.Dock="Top">
<Button Name="btnBrowseTags">TAGS</Button>
<Button Name="btnBrowseTitles">TITLES</Button>
</WrapPanel>
<ComboBox DockPanel.Dock="Top" Name="cbxCategory">
Example
</ComboBox>
<WrapPanel DockPanel.Dock="Bottom">
<TextBox Name="txtKeyword"></TextBox>
<Button Name="btnFind">Find</Button>
</WrapPanel>
<ListBox Name="lbxBrowse">
</ListBox>
</DockPanel>
</StackPanel>
<StackPanel DockPanel.Dock="Right">
<Button>Example</Button>
</StackPanel>
<Canvas>
</Canvas>
</DockPanel>
And this is my current layout view :
So, what I mean with filling the container are :
Making lbxBrowse to fill the mid-space of the DockPanel inside the left StackPanel.
Making txtKeyword to fill the WrapPanel.
Making stbBottom to fill the WrapPanel.
What I've tried :
It seems i've put them in a DockPanel with LastChildFill="True". But it seems doesn't work.
I don't know about this, since it's not possible to put it into a DockPanel first.
I don't know anything about this.
I don't use fixed size, since I need them to keep neat even when resized in multiple screen resolution. The fixed size on ToolBar and StatusBar seems required, otherwise, the text will be unseen.
P.S. If possible, I prefer the solution to be XAML code, rather than the C# code. Otherwise, C# code is fine too.
Thank you.
You should use a Grid. It is more easier to configure. Here is an example (I don't know exactly how you want to setup your layout).
<Window x:Class="SampleWpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="600">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Margin="5" Content="TAGS"
Grid.Column="0" Grid.Row="0" />
<Button Margin="5" Content="TITLES"
Grid.Column="1" Grid.Row="0" />
<Button Margin="5" Content="EXAMPLES"
Grid.Column="2" Grid.Row="0"
HorizontalAlignment="Right"/>
<ComboBox Margin="5"
Grid.Column="0" Grid.ColumnSpan="2" Grid.Row="1" />
<ListBox Margin="5"
Grid.Column="2" Grid.Row="1" Grid.RowSpan="2" />
<Button Margin="5" Content="EXAMPLE"
Grid.Column="2" Grid.Row="3" HorizontalAlignment="Left" />
</Grid>
</Window>
And the result:
With a grid you can set the height and the width of the columns and rows to a specific value (in points, pixels, cm, etc.), to column content (Auto) or proportional to the grid (with *).
Instead of using a StackPanel and DockPanel you can use Grid and set Grid.ColumnDefinitions and Grid.RowDefinitions. You can specify directly each row Height and each column Width. It's easier to use and it automaticly fit to content and container.

Trouble with Grid and StackPanel - Bindings

OK, I'm having issues properly using a ScrollViewer (containing an ItemsControl) inside a StackPanel.
The thing is the scrolling works, however :
No matter how much the user scrolls down, the bottom lines of the tables are not visible
When scrolling is... "released", the table pops back up...
<ScrollViewer Height="Auto">
<ItemsControl ItemsSource="{Binding Items, Mode=TwoWay}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid VerticalAlignment="Top" Margin="0,0,0,0" x:Name="ResTable">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.10*"/>
<ColumnDefinition Width="0.30*" />
<ColumnDefinition Width="0.30*"/>
<ColumnDefinition Width="0.30*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="{Binding [num]}" HorizontalAlignment="Center" />
<TextBlock Grid.Column="1" Text="{Binding [A]}" HorizontalAlignment="Center" />
<TextBlock Grid.Column="2" Text="{Binding [B]}" HorizontalAlignment="Center" />
<TextBlock Grid.Column="3" Text="{Binding [C]}" HorizontalAlignment="Center" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
Any ideas?
P.S.
I've had a look at some of the other answers to similar issues, but none seems to be working...
My main idea is to display a table, with a fixed header, and scrollable contents (populated via Bindings) - ok, and there are also a couple of things on the top of the page (apart from the table I mean)
I guess the issue is that you should probably use parent element like Grid, not StackPanel, because StackPanel has its drawbacks when resizing child items with scrolls and so on.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Put headers in Grid.Row="0" -->
<!-- Put Scrollviewer in Grid.Row="1" -->
</Grid>
Also Height="Auto" attribute can be removed from ScrollViewer, you might want to use VerticalAlignment="Stretch" for item to take all the available space. I hope this is what you are trying to achieve.

Stackpanel height percentage within a grid

I'm dynamically filling two stackpanels with content at runtime and I want to set the height of these two stackpanels via a percentage. Here's what I've tried:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="3*" />
<RowDefinition Height="2*" />
</Grid.RowDefinitions>
<ScrollViewer HorizontalAlignment="Stretch"
Grid.Row="0">
<StackPanel Name="gridEvents"
Orientation="Vertical"
HorizontalAlignment="Stretch">
<Label Content="Foo" />
</StackPanel>
</ScrollViewer>
<ScrollViewer HorizontalAlignment="Stretch"
Grid.Row="1">
<StackPanel Name="gridNewEvent"
Orientation="Vertical"
HorizontalAlignment="Stretch">
<Label Content="Bar" />
</StackPanel>
</ScrollViewer>
</Grid>
If I change the RowDefinition height to a static value, it works. but not when I try a percentage. Any ideas?
Have you tried setting the height value of your grid? Otherwise it will expand to fill all available space and your rows will fill a percentage of the resulting grid. Also, it looks more like you're setting the value of your scrollviewers. Did you mean to say you were setting the height for those?

Categories