Customizing ScrollViewer Style breaks RichTextBox Mouse Wheel Scrolling - c#

To reproduce this, simply add this style to any wpf project that has a RichTextBox:
https://pastebin.com/dJAqFC3d
And a full minimal project can be located here:
https://drive.google.com/file/d/1a7e-vwKpt1Emg7fhMhVRLccwrjOlhWk1/view?usp=sharing
Also an example of the two styles:
<!--
This style does NOT break RichTextBox Scrolling
-->
<Style TargetType="{x:Type ScrollViewer}">
<Style.Resources>
<SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
</Style.Resources>
</Style>
<!--
The Style below breaks Rich Text Box
-->
<!--<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="CanContentScroll" Value="True"></Setter>
<Setter Property="PanningMode" Value="Both"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollContentPresenter Grid.Column="0" />
<ScrollBar
x:Name="PART_VerticalScrollBar"
Grid.Row="0"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{TemplateBinding VerticalOffset}" />
<ScrollBar
x:Name="PART_HorizontalScrollBar"
Grid.Row="1"
Grid.Column="0"
Maximum="{TemplateBinding ScrollableWidth}"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{TemplateBinding HorizontalOffset}" />
--><!--<Rectangle Grid.Row="1" Grid.Column="1" Fill="Red"/>--><!--
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>-->
Then at the bottom of the style, comment out either of the ScrollViewer styles to swap between them. One simply overrides the bottom right rectangle color. The other does the same, but also defines the scrollbars. The style that defines the scrollbars breaks vertical scrolling.
This can also be reproduced using the official Microsoft provided styles, located here:
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/scrollbar-styles-and-templates?view=netframeworkdesktop-4.8
and here
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/controls/scrollviewer-styles-and-templates?view=netframeworkdesktop-4.8
UPDATE: (The above links will soon be an invalid example, because this issue has been submitted, and it is apparently going to be addressed and fixed)
Does anyone know why declaring a custom style for ScrollViewers breaks RichTextBox mouse wheel scrolling?
Edit: It should also be noted that the above example does not hinder or break the vertical mouse wheel scrolling of any other control (that I've noticed). RichTextBox seems to be an edge case.

Found the solution, and it's actually stupid easy.
You have to add CanContentScroll="True" to the ScrollContentPresenter within the ScrollViewer control template. Here is an example:
<Style TargetType="{x:Type ScrollViewer}">
<Setter Property="CanContentScroll" Value="True"></Setter>
<Setter Property="PanningMode" Value="Both"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ScrollContentPresenter CanContentScroll="True" Grid.Column="0" />
<ScrollBar
x:Name="PART_VerticalScrollBar"
Grid.Row="0"
Grid.Column="1"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"
Value="{TemplateBinding VerticalOffset}" />
<ScrollBar
x:Name="PART_HorizontalScrollBar"
Grid.Row="1"
Grid.Column="0"
Maximum="{TemplateBinding ScrollableWidth}"
Orientation="Horizontal"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"
Value="{TemplateBinding HorizontalOffset}" />
<Rectangle Grid.Row="1" Grid.Column="1" Fill="Red"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
This is not mentioned anywhere within the microsoft style example, and they also ommit it from their suggested style template.

Related

XAML ListView auto width column

I'm trying to develop an universal app for personal use, however I am running into the problem that the second column in my ListView doesn't align properly, I have the following XAML:
<ListView
Grid.Row="1"
ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Stretch="None" Source="{Binding Image}" />
<TextBlock Grid.Column="0" Grid.Row="2" Text="{Binding Name}" HorizontalAlignment="Center" />
<Image Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Source="{StaticResource HighAlchImage}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Which results in the following image:
However, I want the second image (the one that's the same every time) to align with itself, preferably with the width of the first Column to be Auto. Is this possible?
You need to stretch width of the ListViewItem to the width of the ListView.
i.e. You have to set HorizontalContentAlignment of the ListView's ItemContainerStyle to Stretch.
Normally I would create a copy of the Default ListViewItemStyle, then do my customization based on the default style:
(put the following code inside <ListView> Tag)
<ListView.Resources>
<!-- Better to put this to another XAML file -->
<Style x:Key="ListViewItemStyleDefault" TargetType="ListViewItem">
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}"/>
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="TabNavigation" Value="Local"/>
<Setter Property="IsHoldingEnabled" Value="True"/>
<Setter Property="Padding" Value="12,0,12,0"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="MinWidth" Value="{ThemeResource ListViewItemMinWidth}"/>
<Setter Property="MinHeight" Value="{ThemeResource ListViewItemMinHeight}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter CheckBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" ContentMargin="{TemplateBinding Padding}" CheckMode="Inline" ContentTransitions="{TemplateBinding ContentTransitions}" CheckBoxBrush="{ThemeResource SystemControlForegroundBaseMediumHighBrush}" DragForeground="{ThemeResource ListViewItemDragForegroundThemeBrush}" DragOpacity="{ThemeResource ListViewItemDragThemeOpacity}" DragBackground="{ThemeResource ListViewItemDragBackgroundThemeBrush}" DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}" FocusBorderBrush="{ThemeResource SystemControlForegroundAltHighBrush}" FocusSecondaryBorderBrush="{ThemeResource SystemControlForegroundBaseHighBrush}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" PointerOverForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}" PressedBackground="{ThemeResource SystemControlHighlightListMediumBrush}" PlaceholderBackground="{ThemeResource ListViewItemPlaceholderBackgroundThemeBrush}" PointerOverBackground="{ThemeResource SystemControlHighlightListLowBrush}" ReorderHintOffset="{ThemeResource ListViewItemReorderHintThemeOffset}" SelectedPressedBackground="{ThemeResource SystemControlHighlightListAccentHighBrush}" SelectionCheckMarkVisualEnabled="True" SelectedForeground="{ThemeResource SystemControlHighlightAltBaseHighBrush}" SelectedPointerOverBackground="{ThemeResource SystemControlHighlightListAccentMediumBrush}" SelectedBackground="{ThemeResource SystemControlHighlightListAccentLowBrush}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ListViewItemStyleStretch" TargetType="ListViewItem" BasedOn="{StaticResource ListViewItemStyleDefault}">
<!-- Magic here -->
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.Resources>
<ListView.ItemContainerStyle>
<StaticResource ResourceKey="ListViewItemStyleStretch"/>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<!-- Your ItemTemplate... -->
</ListView.ItemTemplate>
The Grid panel has such functionality built in. In order to utilize it you should set SharedSizeGroup on your column definitions, and then set attached Grid.IsSharedSizeScope on the element parenting all grids which should share column sizes (ListView would be a good choice in your case).
<ListView Grid.Row="1"
ItemsSource="{Binding Items, UpdateSourceTrigger=PropertyChanged}"
Grid.IsSharedSizeScope="True">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1" />
<ColumnDefinition Width="Auto" SharedSizeGroup="Column2" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Stretch="None" Source="{Binding Image}" />
<TextBlock Grid.Column="0" Grid.Row="2" Text="{Binding Name}" HorizontalAlignment="Center" />
<Image Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" Source="{StaticResource HighAlchImage}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
You might want to take some care while choosing values for SharedSizeGroup properties - preferably, they should be unique per visual tree.
Do it the opposite:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
This way your first column will use the space it needs and the second column will be aligned.
Searching for a solution, I ended up here, #Ryan answer is near to solve my problem, but some adjusts must be done.
1 Create An style:
<Style x:Key="LstViewItemContainerStyle" TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
2 Apply style to the list view as this:
<ListView
...
ItemContainerStyle="{StaticResource LstViewItemContainerStyle}">
</ListView>

Margin difference in nested ListBox with DataTemplates

I have a problem with my ListBox. I have written several DataTemplates which I use in a ListBox. Each one of these contains a grid and may contain a nested ListBox depending on the item.
My problem is: The height of these nested ListBoxes seem to be different to the root ListBox's height. Additionally it seems, that there is sometimes one pixel margin to the element above.
Has someone encountered this problem, too and maybe solved it?
XAML-Code:
<!-- Template for SubData-Items -->
<DataTemplate x:Key="DataTemplate">
<Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999" Background="Violet">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
<ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
<Line Grid.ColumnSpan="999" Stroke="Black" X1="0" X2="{Binding ElementName=baseGrid, Path=ActualWidth, Mode=OneWay}" Y1="0" Y2="0" VerticalAlignment="Bottom" />
</Grid>
</DataTemplate>
<!-- Template for Items -->
<DataTemplate x:Key="GroupDataTemplate">
<Grid Grid.ColumnSpan="999" Background="Blue">
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Gantt, Path=GridRowHeight}" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid x:Name="baseGrid" Grid.Column="0" Grid.ColumnSpan="999">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ElementName=Col0, Path=Width}" />
<ColumnDefinition Width="{Binding ElementName=Col1, Path=Width}" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=Row0, Path=Height}"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Text="{Binding Bezeichnung}" HorizontalAlignment="Left" VerticalAlignment="Center" FontSize="12" />
</Grid>
<Grid x:Name="expandedGrid" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999">
<ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="0,0,2,0"
ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
</Grid>
</Grid>
</DataTemplate>
<!-- Grid with ListBox -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition x:Name="Row0" Height="34"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="Col0" Width="25" />
<ColumnDefinition x:Name="Col1" Width="*" />
</Grid.ColumnDefinitions>
<ListBox Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="999" ItemsSource="{Binding ItemSource, Mode=OneWay}"
ItemTemplate="{StaticResource GroupDataTemplate}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="Auto"
ScrollViewer.CanContentScroll="true"
ScrollViewer.IsDeferredScrollingEnabled="False"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
FontSize="10" />
</Grid>
qqbenq gave a very nice solution . Here is another way to do it.
the control templates of ListBox and ListBoxItem has padding inside their borders. Thankfully ListBoxItem border's padding can be control by a style like so:
<Style
TargetType="ListBoxItem">
<Setter
Property="Padding"
Value="0" />
</Style>
but unfortunately for the ListBox , you will have to override the default template with all of its details to change its internal border's hard-coded padding like this:
<Style
TargetType="ListBox">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type ListBox}">
<Border
x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="0"
SnapsToDevicePixels="true">
<ScrollViewer
Focusable="false"
Padding="{TemplateBinding Padding}">
<ItemsPresenter
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
<ControlTemplate.Triggers>
<Trigger
Property="IsEnabled"
Value="false">
<Setter
Property="Background"
TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
</Trigger>
<Trigger
Property="IsGrouping"
Value="true">
<Setter
Property="ScrollViewer.CanContentScroll"
Value="false" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
One last note : remove the Margin that you added inside your xaml.
Solution complete
Add a Margin="-2,0,0,0" and a Padding="-1" to your "LBMaGruppen" named ListBox.
<ListBox x:Name="LBMaGruppen" ItemTemplate="{StaticResource DataTemplate}" ItemsSource="{Binding SubdataObjects}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" Height="Auto" Margin="-2,0,0,0" Padding="-1"
ScrollViewer.CanContentScroll="false" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled" BorderThickness="0" />
Also, the "root" element's height is binded to {Binding ElementName=Gantt, Path=GridRowHeight}, while the "sub" element's height to {Binding ElementName=Row0, Path=Height}, so this must cause the difference.
It seems that you have auto height set on all your ListBox. You could try setting the height to a specific size. EDIT: I see you already have ScrollViewer settings. I think setting the height of the box to a specific size instead of auto will do what you want.
As to the padding between elements see the ListBox.ItemContainerSyle which should allow you to set the margin between elements.

List view Repeat Button Hight and width customization

I am trying to apply style for scroll bars of listview control in WPF.
I want to change height and width of the repeat button.
How can I configure this.
I am newbie in WPF can any one help me out in this topic.
Thanks in Advance.
You'll need to modify the default ScrollBar control template. Copy-paste the default style from here, and modify the "HorizontalIncrementTemplate" and "VerticalIncrementTemplate" XAML as needed (in particular for your case, look at modifying the height/width of the Path elements).
Alternatively, you can also use Blend to modify control templates, which you may find easier.
Try this
<ListView>
<ListView.Style>
<Style TargetType="ListView">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListView">
<ScrollViewer>
<ScrollViewer.Style>
<Style TargetType="ScrollViewer">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollViewer">
<!--Grid used for displaying listview item(ScrollContentPresenter Grid.ColumnSpan="2") and vertical scrollviwer(Grid Column="1")-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!--Listview item will display in ScrollContentPresenter-->
<ScrollContentPresenter Grid.ColumnSpan="2"/>
<!--Vertical Scrollviwer style-->
<ScrollBar Name="PART_VerticalScrollBar" Grid.Column="1" HorizontalAlignment="Right" Grid.RowSpan="2" Value="{TemplateBinding VerticalOffset}" Maximum="{TemplateBinding ScrollableHeight}" ViewportSize="{TemplateBinding ViewportHeight}" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}">
<ScrollBar.Style>
<Style TargetType="ScrollBar">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ScrollBar">
<!--you can change height and width of below repeat button -->
<Grid Background="Green">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="18"/>
<RowDefinition Height="0.00001*"/>
<RowDefinition MaxHeight="18"/>
</Grid.RowDefinitions>
<Border Grid.RowSpan="3" CornerRadius="2" Background="#F0F0F0" />
<RepeatButton Grid.Row="0" Height="0" Command="ScrollBar.LineUpCommand" Content="M 0 4 L 8 4 L 4 0 Z" />
<Track Name="PART_Track" Grid.RowSpan="3" IsDirectionReversed="true">
<Track.DecreaseRepeatButton>
<RepeatButton Height="0" Command="ScrollBar.PageUpCommand" />
</Track.DecreaseRepeatButton>
<Track.Thumb>
<Thumb Background="LightGray" Margin="2" />
</Track.Thumb>
<Track.IncreaseRepeatButton>
<RepeatButton Height="0" Command="ScrollBar.PageDownCommand" />
</Track.IncreaseRepeatButton>
</Track>
<RepeatButton Grid.Row="3" Height="0" Command="ScrollBar.LineDownCommand" Content="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ScrollBar.Style>
</ScrollBar>
<!--similarly you can customize for horizontal scrollviwer-->
<ScrollBar Name="PART_HorizontalScrollBar" Orientation="Horizontal" Grid.Row="1" Grid.Column="1" Value="{TemplateBinding HorizontalOffset}" Maximum="{TemplateBinding ScrollableWidth}" ViewportSize="{TemplateBinding ViewportWidth}" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ScrollViewer.Style>
<ItemsPresenter></ItemsPresenter>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListView.Style>
</ListView>
For more details visit

WPF ScrollViewer side

I have a Expander with a nested ScrollViewer as showm below:
Code (simplified version)
<Expander.Content>
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<StackPanel Orientation="Vertical">
<TextBox FontSize="16"
BorderThickness="0"
IsReadOnly="True"
Background="Transparent"
Foreground="MidnightBlue"
TextWrapping="Wrap"
Text="{Binding LoggingMessage, Mode=OneWay}">
</TextBox>
/StackPanel>
</ScrollViewer>
</Expander.Content>
</Expander>
I need to change the side of the ScrollViewer, so its shown on the LEFT side.
what is the simplest solution to this?
You can customize the template of the scrollviewer to change the position of the scrollbar(s) (among other things). The MSDN example of template customisation is actually showing how to move the vertical scrollbar to the left.
http://msdn.microsoft.com/en-gb/library/aa970847(v=vs.85).aspx
Here is the code for convenience:
<Style x:Key="LeftScrollViewer" TargetType="{x:Type ScrollViewer}">
<Setter Property="OverridesDefaultStyle" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollViewer}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ScrollContentPresenter Grid.Column="1"/>
<ScrollBar Name="PART_VerticalScrollBar"
Value="{TemplateBinding VerticalOffset}"
Maximum="{TemplateBinding ScrollableHeight}"
ViewportSize="{TemplateBinding ViewportHeight}"
Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>
<ScrollBar Name="PART_HorizontalScrollBar"
Orientation="Horizontal"
Grid.Row="1"
Grid.Column="1"
Value="{TemplateBinding HorizontalOffset}"
Maximum="{TemplateBinding ScrollableWidth}"
ViewportSize="{TemplateBinding ViewportWidth}"
Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The scrollbar position is defined by the FlowDirection property.
See https://stackoverflow.com/a/22717596/2075605 for more details
The above code is to change from right to left. However, you need from left to Right. Use same code as above but change the scrollcontent presenter to this:
<ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Grid.Column="0" Grid.Row="0"/>
$
I tested it and it worked for me

C#, WPF, Autorezise Listbox when window resize

C#, Visual Studio 2010, dot net 4, WPF, Microsoft Ribbon
I have a WPF window with the ribbon menues at the top of the window and an area below
where I try to fill with my controls however I can not get the controls to rezise with
my window.
The listbox in the below example should be fully "expanded" witin its boundaries when the window appear and its width should follow the window width when the user resize the window
(the user should not resize the controls itself) by dragging i nthe windows sides.
I tried a lot of playing around with the controls and searched the web but have not been able to
find a solution (some site indicated the usage of border would do the trick).
The Image image1 is a background image spanning over the whole "surface".
The Image image2 is a small logo picture.
<DockPanel DockPanel.Dock="Top">
<Grid DockPanel.Dock="Top" Height="526" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2" Name="BaseGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1" />
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" HorizontalAlignment="Left" Name="image1" VerticalAlignment="Top" Source="........./el_bg.jpg" Stretch="None" />
<Grid Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" Margin="2" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Name="image2" Stretch="Fill" VerticalAlignment="Top" Source="........./shiny_rgb.png" />
<ListBox Grid.Column="2" Grid.Row="0" Name="MessageToUser" VerticalAlignment="Top" />
</Grid>
</Grid>
</DockPanel>
Regards
You're setting horizontal alignments to Left that shouldn't be set. Try this:
<DockPanel DockPanel.Dock="Top">
<Grid DockPanel.Dock="Top" Height="526" VerticalAlignment="Top" Margin="2" Name="BaseGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1" />
<RowDefinition Height="60" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" HorizontalAlignment="Left" Name="image1" VerticalAlignment="Top" Source="........./el_bg.jpg" Stretch="None" />
<Grid Grid.Column="0" Grid.Row="1" VerticalAlignment="Top" Margin="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Name="image2" Stretch="Fill" VerticalAlignment="Top" Source="........./shiny_rgb.png" />
<ListBox Grid.Column="2" Grid.Row="0" Name="MessageToUser" VerticalAlignment="Top">
<ListBoxItem>One</ListBoxItem>
<ListBoxItem>Two</ListBoxItem>
</ListBox>
</Grid>
</Grid>
</DockPanel>
In addition, your ListBox is in the third column of its containing Grid. If you want it to stretch across the entire window, you will need to ensure it spans all three columns:
<ListBox Grid.ColumnSpan="3" Grid.Row="0" Name="MessageToUser"
VerticalAlignment="Top">
You should read up on WPF layout - you're setting way more properties here than you need to be. Once you understand it, you'll find this thing much more intuitive. In addition, you can use a tool like Snoop to help figure out what is wrong with your layout.
Applying the following style helped me meet this requirement:
<Style x:Key="listBoxAutoFill" TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="Selector.IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd"
Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
My requirement is more about resizing the listbox height as the window grows/shrinks but the same can be applied for width.
<ListBox Grid.Row="1" Grid.Column="0" Width="158"
ItemContainerStyle="{StaticResource listBoxAutoFill}"
ItemsSource="{Binding ListBoxItems, Mode=TwoWay}" />

Categories