How can I scroll on scaled control? - wpf

I need a zooming mechanism. So I found one on Zoom control to WPF Form which seem to be suitable for me.
I have made a slider and apply ScaleTransform.
My questions is: Is there any way I can wrap this into a scroll viewer so that I could scroll to the enlarged part that is not visible anymore ?
Thanks in advance
Daniel

Yes, you can wrap anything in a scrollviewer.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Slider Grid.Row="0" Grid.Column="0" x:Name="slider" Minimum="1" Maximum="10" />
<ScrollViewer Grid.Row="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<TextBlock Grid.Column="0" Text="1234567890" Background="Yellow">
<TextBlock.LayoutTransform>
<ScaleTransform ScaleX="{Binding Path=Value, ElementName=slider}" ScaleY="{Binding Path=Value, ElementName=slider}" />
</TextBlock.LayoutTransform>
</TextBlock>
</ScrollViewer>
</Grid>

Related

How to cut TextBox width to prevent out of the Grid?

I have the next layout
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Width="60" Height="60" />
<StackPanel Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Horizontal">
<TextBlock Text="Title should be long" HorizontalAlignment="Left" />
<Ellipse Fill="White" Stroke="White" Width="7" Height="7" />
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="1" Text="Message" />
<TextBlock Grid.Row="1" Grid.Column="2" Text="Info" />
</Grid>
I have an issue in the StackPanel which hosts a Title and Ellipse, the goal is the Online marker by the ellipse whitch should be placed at the end off the title. But it shouldn't out of a view part.
I have tried to put TextBox and Ellipse into cells of the Grid unfortunatly it doesn't help.
<Grid Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2">
<Grid.ColumnsDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnsDefinitions>
<TextBlock Grid.Column="0" Text="Title should be long" HorizontalAlignment="Left" />
<Ellipse Grid.Column="1" Fill="White" Stroke="White" Width="7" Height="7" />
</Grid>
In my mind it should render correct, but the ellipse is out of view port again.
This is a Expression Blend layout scrinshots, the same layout is rendering in runtime.
The Grid bounds:
The TextBox bounds:
The Ellipse bounds:
So the TextBox and Ellipse is out of the grid :(
Update: I need the next behaviour of layout
1) Short title, the ellipse attached to the title end
2) Long title, the ellipse attached to the right side of container
I tried your code and it renders fine (in other terms it renders in the viewport. See red arrow). Please find attached a screenshot of the results. (I added the showgridlines just to illustrates the rows and cols)
//--- Changed testing and fixed code for intended effect ---//
Code changes in XAML: Swapped the width values for the columndefinitions. Added Textwrapping to textblock in order to see entire text. (You could opt for texttrimming instead depending on your aesthetics.)
<Grid Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Title should be really really really really really long" HorizontalAlignment="Left" TextWrapping="Wrap" />
<Ellipse Grid.Column="1" Fill="White" Stroke="White" Width="7" Height="7"/>
</Grid>
Outcome:

Display a VisualBrush from a hidden control

I got the following xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock x:Name="_sampleText"
Grid.Row="0"
VerticalAlignment="Stretch"
HorizontalAlignment="Stretch"
Width="200"
Height="50"
FontSize="36"
Text="Hello world"
TextAlignment="Center"
Visibility="Collapsed" />
<Border Grid.Row="1"
Width="{Binding ActualWidth, ElementName=_sampleText}"
Height="{Binding ActualHeight, ElementName=_sampleText}">
<Border.Background>
<VisualBrush Stretch="None"
Visual="{Binding ElementName=_sampleText}" />
</Border.Background>
</Border>
</Grid>
I want my visual to be render even if the control he bind too is not visible. Is there a way of doing that?
You could also place the TextBlock in a Border and make that Hidden:
<Border Visibility="Hidden">
<TextBlock ... />
</Border>
No. If the Visibility=Collapsed then it won't take part in the measure/arrange layout pass and not be rendered (the Width and Height will be 0).
What effect are you trying to achieve? It looks like you want a preview pane? Reply in the comments and we can figure out the best approach.
Edit: There is a way to call the measure/update on a UIElement from code-behind however I think the best-approach for you would be use a BoolToVisibilityConverter.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<CheckBox x:Name="OptionCheckBox" Grid.Row="0" />
<Border Grid.Row="1" Visibility="{Binding Path=IsChecked, ElementName=OptionCheckBox", Converter={StaticResouce BoolToVisibilityConverter}}">
<TextBlock Width="200" Height="50" FontSize="36" Text="Hello world" TextAlignment="Center"/>
</Border>
</Grid>

forcing scrollbars to appear in listbox

Hi can I force scrollbars to appear in listbox when its content do not fit. I really need it.
To create tabcontrol item I concucted this xaml:
<TabControl.ContentTemplate>
<DataTemplate>
<ScrollViewer VerticalScrollBarVisibility="Visible"
HorizontalScrollBarVisibility="Visible">
<Grid Name="RssFeedContainerGrid" >
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<controls:ucRssFeed Grid.Row="1" RssUri="{Binding FeedUri}" />
</Grid>
</ScrollViewer>
</DataTemplate>
</TabControl.ContentTemplate>
and ucRssFeed contains listbox.
Here some xaml from that control where I want scrolling to take place:
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="10" x:Name="RssFeedCellblock">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Vertical" Margin="10" Grid.Column="1" Grid.ColumnSpan="2" Grid.Row="0">
<!-- Topic label-->
<TextBlock Cursor="Hand" FontWeight="Bold" Text="{Binding XPath=title}" Tag="{Binding XPath=link}" Foreground="{StaticResource RSS_Topic_Title}" MouseDown="TextBlock_MouseDown">
</TextBlock>
<!-- Breakline -->
<Line Stroke="{StaticResource RSS_Topic_Title}" Y1="5" Y2="5" X1="0" X2="{Binding ElementName=NewsListBox, Path=ActualWidth}" Opacity="0.7" StrokeThickness="1"/>
<!-- publication date label -->
<TextBlock Text="{Binding XPath=pubDate}" Opacity="0.5" />
<!-- Description textblock -->
<TextBlock FontSize="10" FontFamily="Times New Roman" x:Name="descriptionTextBlock"
Text="{Binding XPath=description, Converter={StaticResource HtmlToPlainTextConverter}}" Margin="10"
TextWrapping="Wrap" />
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You need to set the Height property of your ListBox for the Scrollbar to appear listbox automatically show scrollbar when the content is more

Silverlight PivotItem not scrolling down

PivotItem can't scroll down... Anyone has any ideas as to how I can remedy this?
For whatever the reason just won't scroll down when content that is bound inside the listbox is longer than the height of the page. I tried adding a grid inside the pivotitem with height set to auto, but to no avail.
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<controls:Pivot Height="Auto">
<controls:PivotItem Header="Main Information">
<Border CornerRadius="10" Background="#FF5C7590" Height="Auto" Padding="2" BorderThickness="1">
<ListBox x:Name="lbxPropertyItems">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Margin="5, 0, 0, 0" Grid.Column="0" Text="{Binding Label}" />
<TextBlock Grid.Column="1" Text="{Binding Value}" TextWrapping="Wrap" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</controls:PivotItem>
</controls:Pivot>
</Grid>
Thanks for any advice.
The issue is that a StackPanel has an infinite layout space in which ever orientation it is set, so the ScrollViewer included in the ListBox never gets activated in that direction. The best way to handle it is to host it inside a Grid control with row or column definitions.

Control as background of Grid

I have a grid, and I need to have a control as background of this grid. This control will be a progressbar, but it's my problem how to create it.
I can't find how can I set a control as background of grid.
Have you got any experience with this kind of problem?
<DataTemplate x:Key="TodoItemWeeklyTemplate">
<Grid MinWidth="800" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Source="{Binding Occurrence.Appointment.Icon, Converter={StaticResource imgConverter}}" Width="16" Height="16" Stretch="Fill" />
<TextBlock Grid.Column="1" HorizontalAlignment="Left" MaxWidth="130" Text="{Binding Occurrence.Appointment.Subject}" />
</Grid>
</DataTemplate>
Here is how I would do it:-
<Grid MinWidth="800">
<Rectangle x:Name="Background" Fill="Green" Width="{Binding PercentDone, Converter={StaticConverter WidthConv}, ConverterParameter=800}" HorizontalAlignment="Left" />
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Source="{Binding Occurrence.Appointment.Icon, Converter={StaticResource imgConverter}}" Width="16" Height="16" Stretch="Fill" />
<TextBlock Grid.Column="1" HorizontalAlignment="Left" MaxWidth="130" Text="{Binding Occurrence.Appointment.Subject}" />
</Grid>
</Grid>
Where WidthConv is an instance of a class added to the usercontrol resources that implements IValueConverter. The Convert method would take the input percentage value and apply it to the parameter to return the width the rectangle needs to be to represents that percentage value.
The important point here is that Grid naturaly overlays elements on each other when the occupy the same area.
You cannot set a control as a background as it is of Brush Type.
But if you want to emulate that you can put your Grid in another one like that :
<Grid>
<Grid>
<!-- put your Content here -->
</Grid>
<ProgressBar />
</Grid>

Resources