Silverlight RichTextBox/ListBox/ScrollViewer strange behaviour - silverlight

I have a user control with the following XAML:
<ScrollViewer>
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<RichTextBox>
<Paragraph>
<Run Text="{Binding}"/>
</Paragraph>
</RichTextBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</ScrollViewer>
And code behind:
public partial class MainPage {
public MainPage() {
InitializeComponent();
Items = new ObservableCollection<string>(Enumerable.Range(0, 100).Select(x => "some text"));
DataContext = this;
}
public ObservableCollection<string> Items { get; set; }
}
When this code runs, the vertical scroll bar for the ScrollViewer goes down to the bottom. However, if I remove the binding in the Run in the RichTextBox and hard-code the text:
<Run Text="some text"/>
Now the scroll bar stays at the top (as I would expect).
Is this a bug? If not, what is going on? How can I fix this (note: this is simplified XAML, I need the ScrollViewer because the ListBox is actually in a grid)?

I canĀ“t tell you why the ScrollViewer behaves like that, but i would change the XAML to the following. Then is the scroller at the top, if you use binding or not in the DataTemplate.
XAML:
<ListBox ScrollViewer.VerticalScrollBarVisibility="Auto" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<RichTextBox>
<Paragraph>
<Run Text="{Binding}"/>
</Paragraph>
</RichTextBox>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

Make it Fixed width and Height of scrollviewer depends upon the grid row and column size. it help to fixed size in run time. like that
<ScrollViewer VerticalScrollBarVisibility="Auto" VerticalAlignment="Top" HorizontalScrollBarVisibility="Auto" Width="135" Height="463">
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"></StackPanel>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Left" Orientation="Vertical">
<RichTextBox>
<Paragraph>
<Run Text="{Binding}"/>
</Paragraph>
</RichTextBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I hope its helpful

try setting the listbox's height to auto and make the scrollviewer height fixed. that way, the scrollbars only show when the listbox's height is greater than the scrollviewer's height.
But, looking at the way the objects are defined. You are gonna have one big problem in the future. That is, in SL4, Listboxes take up height and don't give it back. So if you have something that expands inside the listbox (i.e. Accordion items) or allow deleting inside the listbox, the listbox would expand to show all it's items. But once an item is deleted, it will never give back the height. The result would be your scrollbar always shows even when you have nothing more to show at the bottom.
That is completely out of topic but I felt that I should let you know.
I hope I helped, if not now, then for the future.

I finally came up with a solution to this problem. I removed the ScrollViewer from the RichTextBox template.

Set the MaxHeight on the Listbox, this will allow the scrollviewer to only show up when the screen dimensions are too small.

Thank you so much! You just saved me days of pain and suffering... :)
For those (like me) who wonder how to remove the scrollviewer from the rtb template :
Extract the template with blend.
Find the scrollviewer element and replace it with a stackpanel (keep the x:name attribute).

Related

Adding a small popup on a wpf listbox that is already using itemsource

Here is a portion of my wpf-xaml code :
<ListBox x:Name="TestJobSuiteListBox" Grid.Row="1" ItemsSource="{Binding AvailableJobs}" MouseRightButtonDown="TestJobSuiteListBox_OnMouseRightButtonDown">
<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
<ListBoxItem Content="{Binding Name}"/>
</HierarchicalDataTemplate>
</ListBox.ItemTemplate>
</ListBox>
I would like to add another listboxitem to that ListBox and I dont want it to be visible before you rightclick on the listbox. It also should not be bound to the "AvailableJobs" property.
Something like this :
<ListBox x:Name="TestJobSuiteListBox" Grid.Row="1" ItemsSource="{Binding AvailableJobs}" MouseRightButtonDown="TestJobSuiteListBox_OnMouseRightButtonDown">
<ListBox.ItemTemplate>
<HierarchicalDataTemplate>
<ListBoxItem Content="{Binding Name}"/>
</HierarchicalDataTemplate>
</ListBox.ItemTemplate>
<ListBoxItem x:Name="AddJobbListBoxItem" Visibility="Hidden"></ListBoxItem>
</ListBox>
This doesn't work, because of "itemsource must be empty problem"
Anyone have a good Idea of how I could do it ?
I don't need help with the visibility/rightclick functionality.
Thanks in advance, I hope the problem is understandable.
You can put listbox to stackPanel, and disable it's scrolling. Then add that one element also to the stackPanel under the listbox, and finally add that stackPanel to scrollViewer. Then you have listbox with AddButton.
<ScrollViewer>
<StackPanel>
<ListBox ItemsSource="{Binding AvailableJobs}"
ScrollViewer.VerticalScrollBarVisibility="Disabled">
<!-- ... -->
</ListBox>
<Button x:Name="AddJobbButton" Visibility="Collapsed" />
</StackPanel>
</ScrollViewer>
Notice that if you have lots of items in listbox, there might be some performance problems, because I'm not sure that listbox's virtualizing is working correctly if it's in stackPanel.
EDIT: of course you have to listen mouse events and set then button's visibility to visible and so on...
I think you have to use ItemTemplateSelector to achieve this functionality. You can create different DataTemplate as per your requirement in the Resources section and bind properly in the xaml. Check the answer here, it will give you the idea about the approach. Please refer this examlpe also. Hope this will help.

How do you make a vertically scrolling scrollviewer inside a tabControl?

I want to make it so that my TabControl is vertically scrollable, but I can't seem to do it. The following sample acts as though there was no scrollviewer at all. I even tried putting the TabControl inside the scrollviewer, or putting it all in a grid and constraining the height of the grid, but nothing works.
<DataTemplate x:Key="tabControlTemplate">
<TabControl ItemsSource="{Binding guiItems}" DisplayMemberPath="Title" Height="Auto" Template="{StaticResource mainTabControlTemplateEx}">
<TabControl.ContentTemplate>
<DataTemplate>
<ScrollViewer Grid.Row="1" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<StackPanel Margin="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ItemsControl ItemsSource="{Binding guiItems }" ItemTemplateSelector="{DynamicResource templateSelector}"/>
</StackPanel>
</ScrollViewer>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</DataTemplate>
The actual problem is not clear from the question.
You are not getting to see scrollviewer and the content inside is clipped? PLease confirm if that is the case.
If the problem is you are getting to see entire content taking up all the available space, and you would like to control that using scroll viewer, then you would need to set 'MaxHeight' property on Scroll Viewer. This would limit the height of your DataTemplate and would make verticall scroll bar visible if the inner content goes beyond the MaxHeight.
Hope that helps.

WPF disable ListBox autosizing in uniform grid

i do have the following structure:
<UniformGrid HorizontalAlignment="Stretch" Grid.Row="0" VerticalAlignment="Top" Columns="6" DockPanel.Dock="Right" >
<StackPanel HorizontalAlignment="Stretch">
<DockPanel Background="#FF393939" >
<Label Content="{lex:Loc Site}" Foreground="#FFE0E0E0"/>
</DockPanel>
<ListBox Height="300" ItemsSource="{Binding Sites.View}" DisplayMemberPath="Name.ActualTranslation">
</ListBox>
</StackPanel>...
These stackpanels in my UniformGrid should be spreaded over the whole MainWindow (or View)... Still if there is an item in a Listbox which has a longer string which needs more place than the standard width it autofits the string and i have to scroll vertically.
I dont want the listview to gain the width if the content has not enough place.
I also have a scrollviewer in my MainWindow in which this view is placed...
What can i do that the uniform grid stays the same width like the MainWindow-...
I've already tried to give a name to the MainWindow and Bind the width to something like this: Width="{Binding ElementName=MainWindow, Path=ActualWdith}" ..
though i get the error:
Cannot find source for binding with reference 'ElementName=MainWindow'. BindingExpression:Path=ActualWdith; DataItem=null;
What can i do to fix this issue?
If you need more information or my error description isnt clear dont hesitate to ask.
UPDATE:
how it should be:
behavior when the text is too long:
and a scrollbar appears on the bottom..
If you are trying to access a WPF object by name it needs to have x:Key="name" which wasn't shown in your code above, i.e.
<Window x:Name="MainWindow" ....
Alternatively you can walk back up the tree until you find an object of the correct type,
Width="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type MainWindow}, Path=ActualWidth}"
Alternatively you can simply change the way you show the text to constrain its width
<ListBox Height="300" ItemsSource="{Binding Sites.View}" DisplayMemberPath="Name.ActualTranslation">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" TextWrapping="Wrap" MaxWidth="200"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

WPF ScrollViewer not activating on Window Resize

This may have been asked, but wasn't able to find the exact question.
Basically I have a WPF Window that I use as a Form. Now for the form, I have a StackPanel that helps keep all the controls and labels in place.
If the user has a smaller resolution display, the window size will be slower so for example 800x600. Some controls get lost.
For this I have added a ScrollViewer wrapped around the StackPanel. But the ScrollViewer never activates. Its probably got something to do with the stackpanel never being limited I suppose. But how can I activate the scroll viewer if the user resizes the window, or the window (when it opens) cannot display all contents properly?
I don't think its necesary to put my xaml here, but if you need it let me know. thanks!
A StackPanel has infinite size (doesn't respect its parent bounds) so you should wrap it in a Grid, which in turn is inside the ScrollViewer.
This may help you
<StackPanel Orientation="Vertical">
<ScrollViewer Name="scrollViewer1">
<DataGrid Name="dgDataList" ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridTemplateColumn Header="View" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
//control like textblock, image etc
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</ScrollViewer>
<ScrollViewer Name="scrollViewer2" >
<DataGrid Name="dgDataList2" ItemsSource="{Binding}" >
<DataGrid.Columns>
<DataGridTemplateColumn Header="View" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
//control like textblock, image etc
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</ScrollViewer>
</StackPanel>
I ran into a similar problem where the horizontal scrollbar wasn't being displayed even though there was content on the screen that was hidden.
<Window x:Class="WPFTestingPlatform.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="{Binding SystemParameters.PrimaryScreenHeight}"
Width="{Binding SystemParameters.PrimaryScreenWidth}"
ResizeMode="CanResizeWithGrip">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel Width="1248" Height="600">
<TextBlock HorizontalAlignment="Right">Right</TextBlock>
</StackPanel>
</ScrollViewer>
</Window>
Set the window to have the size you would like for your window. Also set the Stackpanel size so it neatly fits all of your content.
The window size isn't as important as setting the StackPanel height/width otherwise the StackPanel will inherit it's size from the window.
You can resize this window and the scrollbars will appear/disappear (if ResizeMode="CanResizeWithGrip" is set). If you do not set HorizontalScrollBarVisibility, the scrollviewer will not display the horizontal scrollbar regardless of the content size.

Why might a silverlight ListBox on Windows Phone not allow me scroll all the way down to the bottom?

I have a ListBox in a grid that gets databound when the page loads... pretty straightforward. The problem I'm having is that, after the box is databound, I can scroll... but not all the way to the bottom of the list. It stops an item or two short and won't let me scroll anymore. Here's the listbox XAML:
<Grid x:Name="ContentGrid" Grid.Row="2">
<ListBox x:Name="lbFeed" ItemsSource="{Binding Items}" SelectionChanged="lbFeed_SelectionChanged" VerticalAlignment="Top" Width="480">
<ListBox.ItemTemplate>
<DataTemplate x:Key="MyDataTemplate">
<StackPanel Orientation="Vertical" Width="430">
<TextBlock Text="Some text" TextAlignment="Center" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
I can post more code, but I'm still getting my feet wet in XAML and I'm not sure what might be causing this. If you need more context, let me know and I'll add it here.
This is a known issue at this stage of ctp release if you happen to have rows that are not fixed height. If this is the case you will likely notice your scrolling is a bit jittery too. Fix the height of your content for now if this is the case for your app and all is resolved.

Resources