Displaying a large image in ScrollViewer in WPF - wpf

I want to display a large image in a Window where the Image will have scroll bars if it too big for the area of the screen it is in.
Underneath the image I want a button panel. For this I have put the Image inside a ScrollViewer in a DockPanel that contains a StackPanel to contain the Buttons in the Bottom part. The idea is to click the Browse button to set the image (from code behind handling Button Click)
The following example I put together will just keep the image size (2144 x 1424) and I cannot see the lower button panel.
<Window x:Class="WpfIssues.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfIssues"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DockPanel>
<TextBlock Text="Test Image" FontSize="30" DockPanel.Dock="Top"></TextBlock>
<StackPanel Orientation="Vertical">
<DockPanel x:Name="PhotoPanel">
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Click="Button_Click">Browse...</Button>
</StackPanel>
<ScrollViewer
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<StackPanel>
<Image x:Name="PhotoImage"
Stretch="None"
Source="Resources/bear grills.png"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</StackPanel>
</ScrollViewer>
</DockPanel>
</StackPanel>
</DockPanel>
</Grid>
</Window>
I cant figure out why.

Try putting the button before the scrollviewer, like this:
<DockPanel>
<TextBlock Text="Test Image" FontSize="30" DockPanel.Dock="Top" />
<Button Content="Browse..." DockPanel.Dock="Bottom" />
<ScrollViewer
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto">
<Image x:Name="PhotoImage"
Stretch="None"
Source="http://images6.fanpop.com/image/photos/33600000/Bear-Grylls-bear-grylls-33656894-3504-2336.jpg"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</ScrollViewer>
</DockPanel>

Related

Change the height of the title bar

Question: Can we change the height of the title bar displayed in MahApps.Metro?
Details: For instance, in the following XAML example from the MahApps team, I want to display the content Deploy CupCake - of the TextBlock - below the image of the CupCake. So I removed the Orientation="Horizontal" from the StackPanel in the following XAML. As shown in the snapshot below, the content Deploy CupCake is now showing below the image of CupCake - but it is hiding almost all of it. How can we make this content show all of it below the CupCake image?
Snapshot of the Toolbar with MahApps.Metro: Only about 10% of the content is showing below the image.
<mah:MetroWindow x:Class="SampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
GlowBrush="{DynamicResource MahApps.Brushes.Accent}"
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<mah:MetroWindow.LeftWindowCommands>
<mah:WindowCommands>
<Button Click="LaunchGitHubSite" ToolTip="Open up the GitHub site">
<iconPacks:PackIconModern Width="22"
Height="22"
Kind="SocialGithubOctocat" />
</Button>
</mah:WindowCommands>
</mah:MetroWindow.LeftWindowCommands>
<mah:MetroWindow.RightWindowCommands>
<mah:WindowCommands>
<Button Click="DeployCupCakes" Content="Deploy CupCakes">
<Button.ContentTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<iconPacks:PackIconModern Width="22"
Height="22"
VerticalAlignment="Center"
Kind="FoodCupcake" />
<TextBlock Margin="4 0 0 0"
VerticalAlignment="Center"
Text="{Binding}" />
</StackPanel>
</DataTemplate>
</Button.ContentTemplate>
</Button>
</mah:WindowCommands>
</mah:MetroWindow.RightWindowCommands>
<Grid>
<!-- Your content -->
</Grid>
</mah:MetroWindow>
First of all, it is better to use a to use a panel that distributes the available space among its content, like a Grid, to prevent cutting off content as with the StackPanel. Here, the data template defines a Grid with two rows, where the TextBlock scales to its desired size and the icon takes up the remaining available space. Also note the HorizontalAlignment of the icon, it is centered.
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<iconPacks:PackIconModern Grid.Row="0"
Width="22"
Height="22"
HorizontalAlignment="Center"
Kind="FoodCupcake" />
<TextBlock Grid.Row="1"
Margin="4 0 0 0"
VerticalAlignment="Center"
Text="{Binding}" />
</Grid>
</DataTemplate>
The same result could also be achieved using a DockPanel, where the last child (in this case the icon) takes up the remaining available space, so the order of the defined controls is important.
<DataTemplate>
<DockPanel>
<TextBlock DockPanel.Dock="Bottom"
Margin="4 0 0 0"
VerticalAlignment="Center"
Text="{Binding}" />
<iconPacks:PackIconModern DockPanel.Dock="Top"
Width="22"
Height="22"
HorizontalAlignment="Center"
Kind="FoodCupcake" />
</DockPanel>
</DataTemplate>
In both cases you will get the result below, a button with a centered icon and a text below.
To make the button more prominent, change the title bar height with the TitleBarHeight property.
<mah:MetroWindow x:Class="SampleApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="MainWindow"
Width="800"
Height="450"
GlowBrush="{DynamicResource MahApps.Brushes.Accent}"
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"
TitleBarHeight="50">

Textbox does not show a verticalscrollbar

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" x:Class="WpfApplication1.MainWindow"
Title="MainWindow" Height="350" Width="550" MinHeight="350">
<DockPanel Background="BlanchedAlmond">
<DataGrid Background="YellowGreen" DockPanel.Dock="Top" MinHeight="100">
</DataGrid>
<StackPanel DockPanel.Dock="Bottom" Orientation="Horizontal" FlowDirection="RightToLeft" Margin="10" Background="YellowGreen">
<Button HorizontalAlignment="Right" Click="Button1Add_Click" Margin="5,0">Add text 1</Button>
<Button HorizontalAlignment="Right" Click="Button2Add_Click">Add text 2</Button>
<Button HorizontalAlignment="Right" Click="Button1_Click" Margin="5,0">Toggle textbox 1</Button>
<Button HorizontalAlignment="Right" Click="Button2_Click">Toggle textbox 2</Button>
</StackPanel>
<Grid Background="Red">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBox x:Name="TextBox1" Grid.Row="0" Background="AliceBlue" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">Test 1</TextBox>
<TextBox x:Name="TextBox2" Grid.Row="1" Background="AliceBlue" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">Test 2</TextBox>
</Grid>
</DockPanel>
</Window>
In the example above I am trying to achieve that the two textboxes in the middle just fill the available space between the top datagrid and the bottom stackpanel with buttons.
They have to divide that space between them depending on their text-content and their visibility.
Both properties can change by databindings, I simulated that with the click events.
But when the space is filled up they have to show a vertical scrollbar when needed.
The code sample above is not good. When I add text to a textbox, the grid-row becomes larger but disappears from the visible region, no scroll bar.
EDIT: I ended up with:
<ScrollViewer Background="AliceBlue" VerticalScrollBarVisibility="Auto">
<StackPanel Orientation="Vertical">
<Label x:Name="Label1" Margin="0,6,0,0">Test 1:</Label>
<TextBox x:Name="TextBox1" Padding="0,6"></TextBox>
<Label x:Name="Label2" Margin="0,6,0,0">Test 2:</Label>
<TextBox x:Name="TextBox2" Padding="0,6" ></TextBox>
</StackPanel>
</ScrollViewer>
You need to add a ScrollViewer in your XAML around the content.
ScrollViewer on MSDN
<ScrollViewer>
Content
</ScrollViewer>

How to add a horizontal button row between a ViewBox and an Image in WPF?

I'm trying to add a row of horizontal button at the top of a form between an image and a view box but when I add the button it fills the image. I tried adding a grid to contain the buttons but that filled the image element. Does anyone know how I would achieve this?
I'm sure there must be a quick fix to this,could someone explain why this happens? I usually use the designer but I think in this case I should have a better understanding of the xaml elements and the properties.
This is how I define the layout for the window:
<Window x:Class="KinectKickboxingBVversion1.ConditioningFrm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ConditioningFrm" Height="377.612" Width="637.313">
<Grid>
<Viewbox Grid.Row="1" Stretch="Uniform" HorizontalAlignment="Center">
<Image Name="Image" Width="640" Height="250"/>
</Viewbox>
</Grid>
</Window>
Setting image source to bitmap:
KinectVideo.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,
PixelFormats.Bgr32, null, colorData, colorFrame.Width * colorFrame.BytesPerPixel)
If you want to put it on the top of the form with no scaling, do this:
<Window x:Class="KinectKickboxingBVversion1.ConditioningFrm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ConditioningFrm" Height="377.612" Width="637.313">
<Grid>
<Grid.RowDefinitions>
<RowDefintion Height="Auto" />
<RowDefintion Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<Button Content="1"/>
<Button Content="2"/>
<Button Content="2"/>
</StackPanel>
<Viewbox Grid.Row="1" Stretch="Uniform" HorizontalAlignment="Center">
<Image Name="Image" Width="640" Height="250"/>
</Viewbox>
</Grid>
</Window>
If you really want to add the StackPanel of buttons in the Viewbox, do this:
<Window x:Class="KinectKickboxingBVversion1.ConditioningFrm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ConditioningFrm" Height="377.612" Width="637.313">
<Viewbox Stretch="Uniform" HorizontalAlignment="Center">
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<Button Content="1"/>
<Button Content="2"/>
<Button Content="2"/>
</StackPanel>
<Image Name="Image" Width="640" Height="250"/>
</StackPanel>
</Viewbox>
</Window>
Setting image source to bitmap:
KinectVideo.Source = BitmapSource.Create(colorFrame.Width, colorFrame.Height, 96, 96,
PixelFormats.Bgr32, null, colorData, colorFrame.Width * colorFrame.BytesPerPixel)

Stretching of WPF StackPanel

I'm playing around with WPF and I'm trying to create an ImageButton control. I've created a UserControl as follows:
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="WpfPractise.Controls.ImageButton"
Height="auto" Width="auto" x:Name="ImageButtonControl">
<Button>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Image Source="{Binding Image, ElementName=ImageButtonControl}"
Width="16" Height="16"
Margin="5,0,0,0" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Text, ElementName=ImageButtonControl}"
Margin="5,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</Button>
This is working fine except for the StackPanel doesn't stretch to fill the width or the height! I've tried a Grid in it's place but to no avail. Any ideas where I'm going wrong?
Example:
If you want to align the Button content to the left then you have to set the HorizontalContentAlignment of the button
<Button HorizontalContentAlignment="Left" VerticalContentAlignment="Center">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch">
<Image Source="{Binding Image, ElementName=ImageButtonControl}"
Width="16" Height="16"
Margin="5,0,0,0" VerticalAlignment="Center"/>
<TextBlock Text="{Binding Text, ElementName=ImageButtonControl}"
Margin="5,0,0,0" VerticalAlignment="Center"/>
</StackPanel>
</Button>

Frame Page controls layout

Could you please tell me where I have gone wrong, my frame size takes the size of the wpf window, code is:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="BSP" Height="700" Width="990" WindowStartupLocation="CenterScreen">
<Grid Background="Green" VerticalAlignment="Center" HorizontalAlignment="Center" >
<Frame Name="MainFrame" Source="LoginScreen.xaml" NavigationUIVisibility="Hidden" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
</Grid>
</Window>
The page size less than the window and also the total size of margin+width+size of label is less than the size of page yet the button is being displayed as cut. Code for the page is below:
<Page x:Class="Loggedin"
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"
Height="660" Width="920"
Title="Loggedin">
<Grid Background="white" Margin="2">
<StackPanel Orientation="Horizontal" VerticalAlignment="Top" >
<Label Content="Loggedin as" Height="28" HorizontalAlignment="Left" Name="Loggedinas" />
<Button Content="LogOut" Margin="780,0,0,0" Height="28" Name="Logout" Width="50" HorizontalAlignment="Right"/>
</StackPanel>
</Grid>
</Page>
Could you please assist me, it is eating my brain from 2 days :(. Following are pics of output:
Pic from Visual Studios: http://clip2net.com/s/1Fpb7
Pic from Runtime: http://clip2net.com/s/1FpbQ
Have you thought about using a DockPanel instead of a StackPanel? It seems to be a closer fit for the layout you're trying to achieve :
<DockPanel VerticalAlignment="Top">
<Label Content="Loggedin as" Height="28" HorizontalAlignment="Left" Name="Loggedinas" />
<Button Content="LogOut" Height="28" Name="Logout" Width="50" HorizontalAlignment="Right"/>
</DockPanel>
Any time you have margins that look like Margin="780,0,0,0" it usually means you're working too hard and there's a better way to do it. In my quick scratch tests, the 780 pixel left margin was pushing the button off the frame.

Resources