Fixed sized usable page with Template 10 with Hamburger? - c#

I'm trying to create a drawing surface within a Template 10 UWP Hamburger template app with a template image in the background. Is there any way to force the main visual space to be non-scrollable? When I use the following XAML, the image expands off the screen as I stretch the app window wider.
<!-- content -->
<StackPanel EntranceNavigationTransitionInfo.IsTargetElement="True"
Padding="12,8,0,0"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="pageHeader">
<StackPanel Orientation="Horizontal">
<ComboBox Name="TemplateComboBox" ItemsSource="{x:Bind _templates}" SelectionChanged="TemplateComboBox_SelectionChanged" PlaceholderText="Select a template...">
<ComboBoxItem Content="{Binding}" />
</ComboBox>
<TextBlock x:Name="stateTextBox"
Margin="16,0,0,0"
Text="Current Visual State" />
</StackPanel>
<Grid Name="DrawingGrid" Margin="0,5,5,5" >
<Image Name="TemplateImage" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Stretch="Uniform" />
</Grid>
</StackPanel>
There is code in the code-behind to set the Image source as the combo selection changes. I just want the image to stretch to the current viewable area.
sigh Haven't even started with the Ink yet :(

You could think about detecting the visible area's width and height, then set the width and height as your image control's width and height.
<Grid EntranceNavigationTransitionInfo.IsTargetElement="True"
Padding="12,8,0,0"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.AlignLeftWithPanel="True"
RelativePanel.AlignRightWithPanel="True"
RelativePanel.Below="pageHeader">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="9*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<ComboBox Name="TemplateComboBox" PlaceholderText="Select a template...">
<ComboBoxItem Content="{Binding}" />
</ComboBox>
<TextBlock x:Name="stateTextBox"
Margin="16,0,0,0"
Text="Current Visual State" />
</StackPanel>
<Grid Margin="0,5,5,5" x:Name="grid" Grid.Row="1">
<ScrollViewer Name="scrollviewer" Width="{Binding ElementName=grid,Path=Width}" Height="{Binding ElementName=grid,Path=Height}" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden">
<Image Name="TemplateImage" VerticalAlignment="Stretch" Source="/Assets/pic.jpg" HorizontalAlignment="Stretch" Stretch="Uniform" />
</ScrollViewer>
</Grid>
</Grid>
private void Page_SizeChanged(object sender, SizeChangedEventArgs e)
{
TemplateImage.Width = scrollviewer.ViewportWidth;
TemplateImage.Height = scrollviewer.ViewportHeight;
}

Related

C# WPF XAML Minimap

How I can build a minimap like in Visual Studio Code, Visual Studio, Sublime Text?
Minimap
I have 2 horizontal StackPanels.
Top: StackPanel with content
Bottom: Minimap StackPanel with Height 100 just shows the content from the top StackPanel in miniature without adding the same content from the top StackPanel.
<Grid>
<ScrollViewer
x:Name="scrollViewer"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled">
<WrapPanel
x:Name="wrapPanel"
Orientation="Horizontal"
Margin="0,0,0,100" />
</ScrollViewer>
<ScrollViewer
x:Name="scrollViewerMiniMap"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Disabled"
VerticalAlignment="Bottom"
Height="100">
<WrapPanel
x:Name="wrapPanelMiniMap"
Orientation="Horizontal" />
</ScrollViewer>
</Grid>
How I can achieve this?
Just create a VisualBrush from the content e.g. using the root container of the content. Override the default style for the ScrollViewer to paint the background of the track with the VisualBrush.
To create a simple dynamic preview just use a Rectangle and set Fill to the VisualBrush. If you want to allow resizing host the Rectangle inside a ViewBox.
To get an initial width with the correct aspect ratio just bind the Rectangle to the ActualWidth and ActualHeight of the container element that serves as the Visual for the VisualBrush:
<Grid>
<Grid.Resources>
<VisualBrush x:Key="VisualBrush"
Visual="{Binding ElementName=StackPanel}"/>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel x:Name="StackPanel"
Orientation="Horizontal">
<StackPanel>
<TextBlock Text="ComboBox1 Label" />
<ComboBox />
</StackPanel>
<StackPanel>
<TextBlock Text="ComboBox2 Label" />
<ComboBox />
</StackPanel>
</StackPanel>
<Viewbox Grid.Row="1">
<Rectangle Width="{Binding ElementName=StackPanel, Path=ActualWidth}"
Height="{Binding ElementName=StackPanel, Path=ActualHeight}"
Fill="{StaticResource VisualBrush}" />
</Viewbox>
</Grid>

How to have the scrollview affect the inner frame only, not whole app

In writing a XAML/UWP/C# app I have the MainPage.xaml, which contains a header menu (home|back|forward navigation and user display buttons), and page navigation menu (left side) split panel, other side of the split is a frame for displaying the pages.
Following is a simplified version of the code (Note that nowhere in this code is a ScrollView):
<Page
x:Class="PowderTracks.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PowderTracks"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Width="1200"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<GridView Height="Auto">
<StackPanel
Width="Auto">
<StackPanel x:Name="headerMenu"
Orientation="Horizontal"
Background="#FF016B3B"
Width="Auto"
Padding="0,0,0,0" >
<Button x:Name ="HomeButton"
Foreground="#FFC0FFC0"
Margin="10,0,0,0"
Background="#33016B3B">
<Image Source="Assets\Home.png" Width="64" />
</Button>
<Button x:Name ="BackButton"
Foreground="#FFC0FFC0"
Padding="0,0,0,0"
Background="#33016B3B">
<Image Source="Assets\Back.png" Width="64" />
</Button>
<Button x:Name ="ForwardButton"
Foreground="#FFC0FFC0"
Padding="0,0,0,0"
Background="#33016B3B">
<Image Source="Assets\Forward.png" Width="64" />
</Button>
<Button x:Name="btnFace" Background="#33016B3B">
<Image x:Name="userPic" Width="32" Height="32"/>
<Button.Flyout>
<Flyout>
<StackPanel>
<Image x:Name="foPic" Width="96" Height="96"/>
<TextBlock Name="foDisplayName" />
<TextBlock Name="foEmail" />
</StackPanel>
</Flyout>
</Button.Flyout>
</Button>
<TextBlock Name="lblUsername"
x:FieldModifier="public"
Text=""
Margin="10,0,0,0"
Height="25"
FontSize="18"
VerticalAlignment="Center"
Foreground="#FFC0FFC0"
/>
<ToggleSwitch x:Name="btnDatabase"
Margin="50,0,0,0"
OffContent="TestDB"
OnContent="LiveDB"
HorizontalAlignment="Right"
Visibility="Visible"
/>
</StackPanel>
<SplitView x:Name="svFrame"
IsPaneOpen="True"
DisplayMode="Inline"
OpenPaneLength="80" Height="Auto" Width="1024">
<UIElement.RenderTransform>
<MatrixTransform/>
</UIElement.RenderTransform>
<SplitView.Pane>
<StackPanel>
<Button Name="btnTracker"
Width="80"
Height="65"
Padding="0,0,0,0">
<Image Source="Assets\trackers.png"
Width="64"/>
</Button>
<Button Name="btnTasks"
Width="80">
<Image Source="Assets\tasksIcon.png"
Width="64"/>
</Button>
<Button Name="btnRFP"
Width="80">
<Image Source="Assets\proposals.png"
Width="64"/>
</Button>
<Button Name="btnFM"
Width="80">
<Image Source="Assets\folderMachine.png" Width="64"/>
</Button>
<Button Name="btnClients"
Width="80" >
<Image Source="Assets\clients.png"
Width="64"/>
</Button>
<Button Name="btnMaint"
Width="80"
Padding="0,0,0,0">
<Image Source="Assets\maintenance.png"
Width="64"
Margin="0,0,0,0"/>
</Button>
</StackPanel>
</SplitView.Pane>
<Frame x:Name="content"
Padding="10,10,10,15"
HorizontalAlignment="Left"
Width="Auto"
Height="Auto"
VerticalAlignment="Top"/>
</SplitView>
</StackPanel>
</GridView>
</Page>
(Click events were removed to make it just copy/paste.)
Anyway, the first opening page is the Proposals page (because this is the one I've been working on), and it is a long page with many controls. I want the scroll view to move the Proposals (or whatever pages come after) page without moving the header menu or the left-side navigation menu. Right now if I scroll the entire app scrolls, so the header and navigation menus scroll up as the page scrolls.
What I have tried:
Placing the ScrollView on the <Frame x:Name...> panel - does not work.
Placing the ScrollView on the Proposals Page in the top level StackPanel
<StackPanel Margin="0,0,10,27"
VerticalAlignment="Top"
ScrollViewer.VerticalScrollBarVisibility="Visible">
Doesn't work.
I've tried to follow the example on these sites:
https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.scrollviewer?view=winrt-18362
https://learn.microsoft.com/en-us/windows/uwp/design/controls-and-patterns/scroll-controls
Thank you in advance.
GridView is usually used together with ItemTemplate and ItemsSource. This control is to quickly generate a batch of items with the same layout (such as the Windows Settings home page) based on the data set, rather than being used as a layout container. Here is the related document
GridView is a combination of multiple controls. The reason why your application scrolls is because the GridView contains a ScrollViewer.
Based on the code you provided, you can try this layout:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<StackPanel>
<!-- Header Buttons -->
</StackPanel>
<SplitView Grid.Row="1">
<SplitView.Pane>
<!-- Pane List -->
</SplitView.Pane>
<SplitView.Content>
<ScrollViewer>
<Frame x:Name="content"/>
</ScrollViewer>
</SplitView.Content>
</SplitView>
</Grid>
This ensures that only the content inside the Frame will scroll.
Thanks.
My guess would be to do this:
<ScrollViewer Padding="10,10,10,15"
HorizontalAlignment="Stretch"
Width="Auto"
Height="Auto"
VerticalAlignment="Stretch">
<Frame x:Name="content" />
</ScrollViewer>
Important thing to remember is that ScrollViewer size needs to constrained - ScrollViewer itself cannot grow when content grows, because then it will not be able to properly generate the scroll bars

C# WPF - Dockpanel's children collapsed not resizing the other visible childs

I'm sorry if I didn't find any relative post/questions regarding my small annoying issue.
I have a WPF window with a DockPanel (LastChildFill = True) that hosts three controls :
One Button (OK)
One label (Title)
One Border with a listbox in it
What I do is when the test in process is "pass" it has no data to push in the listbox so I make it collapsed and then I would like the Title label to be centered in the available space that is not used by the listbox and its border.
When I have a "fail" or an "error", I have data to put in the listbox and then it is visible and everything is just as expected.
I tried many things before coming here and I lost enough time on this as I need to get other stuff done by the time I'm writing here.
Can anyone point me out how to solve my issue (centering label when listbox+border is collapsed) ?
Here is my xaml code for this window :
<Window x:Class="NI.TestStand.WPFControls.Views.DisplayBannerView"
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:NI.TestStand.WPFControls"
mc:Ignorable="d"
Title="DisplayBanner" x:Name="DisplayBannerMessage" Height="500" Width="800" MinHeight="300" MinWidth="500">
<Window.Resources>
<Style x:Name="BaseWindowFont" TargetType="Window">
<Setter Property="FontFamily" Value="Arial"></Setter>
<Setter Property="FontSize" Value="16"></Setter>
</Style>
</Window.Resources>
<Grid>
<Border BorderBrush="Black" BorderThickness="2">
<DockPanel LastChildFill="True">
<Button
x:Name="butOK"
DockPanel.Dock="Bottom"
Margin="10" Content="OK"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Padding="10" Width="150"
Click="butOK_Click"/>
<Label
x:Name="main_message"
Padding="15"
FontSize="50"
Content="MAIN_MSG"
DockPanel.Dock="Top"
HorizontalAlignment="Center"
VerticalContentAlignment="Center" />
<Border BorderBrush="Chocolate" BorderThickness="2" Margin="10" Name="messages_border">
<ListBox
Background="{Binding ElementName=DisplayBannerMessage, Path=Background}"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
VerticalContentAlignment="Top"
VerticalAlignment="Stretch"
x:Name="detail_message">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" ToolTip="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
</DockPanel>
</Border>
</Grid>
</Window>
Here are the images that shows a PASS and an ERROR to show the difference.
The PASSED title message in the green lime window should go in the middle of the window as the listbox is collapsed..
Thanks for all your help and time
I would design the whole thing like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderBrush="Black" BorderThickness="2"
Grid.RowSpan="{Binding PassErrorBooleanProperty, Converter={StaticResource BoolToRowSpanConverter}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label
x:Name="main_message"
Padding="15"
FontSize="50"
Content="MAIN_MSG"
DockPanel.Dock="Top"
HorizontalAlignment="Center"
VerticalContentAlignment="Center" />
<Border Grid.Row="1" BorderBrush="Chocolate" BorderThickness="2" Margin="10" Name="messages_border"
Visibility="{Binding PassErrorBooleanProperty, Converter={StaticResource BoolToVisibilityConverter}}">
<ListBox
Background="{Binding ElementName=DisplayBannerMessage, Path=Background}"
Foreground="Black"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
VerticalContentAlignment="Top"
VerticalAlignment="Stretch"
x:Name="detail_message">
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" ToolTip="{Binding}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Border>
<Button Grid.Row="2"
x:Name="butOK"
DockPanel.Dock="Bottom"
Margin="10" Content="OK"
HorizontalAlignment="Center"
VerticalAlignment="Top"
Padding="10" Width="150"
Click="butOK_Click" />
</Grid>
</Border>
</Grid>
There are two bindings to PassErrorBooleanProperty (which I've made up as something you'd use to indicate the result, you might have something else in place for this already), and you'd need two different converters, one for converting to a Visibility, and one for converting to an int (Grid.RowSpan).
When the value is true (Pass), you'd return Visibility.Collapsed and 2 from the converters. When the value is false, you'd return Visibility.Visible and 1.
Let me know if you need more info on the converters, though there is lots of information out there on using IValueConverter to create Boolean to Visibility converters, etc.

Dynamic height of StackPanel in ListBox custom ItemTemlate, WP8, C#, WPF

I'm programing app that will display data from RSS feed. I need just little view to show small image and description.
I have custom ListBox with one stackPanel where is an and .
Problem is: each item in that listbox has some height, but i need that height to change dynamically by the length of text and size of image.
There's my ListBox:
<ListBox x:Name="gui_listNovinky" SelectedIndex="-1" Height="500" VerticalAlignment="Top" ScrollViewer.VerticalScrollBarVisibility="Hidden" HorizontalContentAlignment="Stretch" >
<ListBox.ItemTemplate>
<DataTemplate>
<Border BorderThickness="0,1,0,0" BorderBrush="Black" Margin="10">
<StackPanel Name="stackpanel" Orientation="Horizontal" Height="500">
<StackPanel Width="435" Height="1000">
<Image Source="{Binding Image}" Height="200" Width="230" VerticalAlignment="Top"/>
<TextBlock Text="{Binding Description}" MaxHeight="290" FontSize="20" VerticalAlignment="Top" Foreground="Black" TextWrapping="Wrap" />
</StackPanel>
</StackPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And there is how it look like. You can see that annoying free space below the image and the text. So ugly... :(
I will so thankful for solution. :)
PS: If there is mistakes in my English, dont be afraid to ask and i will explain it. :)
Do not enforce size inside data template. Modified DataTemplate which will solve the problem.
<DataTemplate>
<Border BorderThickness="0,1,0,0"
BorderBrush="Black"
Margin="10">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<Image Source="{Binding Image}"
Height="200"
Width="230"
VerticalAlignment="Top" />
<TextBlock Text="{Binding Description}"
MaxHeight="290"
FontSize="20"
Grid.Row="1"
VerticalAlignment="Top"
Foreground="Black"
TextWrapping="Wrap" />
</Grid>
</Border>
</DataTemplate>

Some controls are not stretching [duplicate]

This question already has an answer here:
WPF Grid horizontalalignment doesn't work. Sizes don't changes
(1 answer)
Closed 8 years ago.
In this window I have many different controls and I want to stretch which is possible
but there are some controls by 'stackGroup', 'listBox1', 'listBox2' that don't stretching.. Why ??
Also is this way i right to do this kind of pages
<Window x:Class="TwoColumnGridSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="Window_Loaded"
Title="Window1" Height="759" Width="800">
<Grid Margin="0,0,0,95">
<Grid.RowDefinitions>
<RowDefinition Height="509"></RowDefinition>
<RowDefinition Height="111"></RowDefinition>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Height="472" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="165" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" VerticalAlignment="Stretch" Margin="0,0,0,163">
<ListBox Name="listBox1" SelectedItem="{Binding SelectedItem}" Width="165" ItemsSource="{Binding Buttons}" SelectionChanged="ListBox_SelectionChanged" HorizontalContentAlignment="Left" VerticalAlignment="Stretch" >
<ListBox.ItemTemplate>
<DataTemplate>
<Button Content="{Binding .}" Click="Button_Click" Style="{StaticResource listboxbuttons}"></Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
<StackPanel Name="stackGroup" HorizontalAlignment="Stretch" Grid.Column="1" Height="457" VerticalAlignment="Top" >
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Height="460" Margin="0,0,10,0" >
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="24" />
<RowDefinition Height="316"/>
<RowDefinition Height="60" />
</Grid.RowDefinitions>
<Image x:Name="imageMap" Source="Resources/images.jpg" HorizontalAlignment="Stretch" Grid.Row="0" Stretch="Fill" Margin="2,0,0,0" />
<Border BorderBrush="Green" BorderThickness="3" CornerRadius="1,1,1,1" Margin="2,4,0,17" Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.RowSpan="2">
<Grid Grid.Row="1" Margin="3,3,3,3">
<GroupBox Header="Club Badge" HorizontalAlignment="Left" VerticalAlignment="Top" Height="123" Width="134"/>
<GroupBox Header="Goalie" HorizontalAlignment="Left" VerticalAlignment="Top" Height="179" Width="134" Margin="0,128,0,0"/>
<GroupBox Header="Defender" HorizontalAlignment="Left" Margin="139,0,0,0" VerticalAlignment="Top" Height="307" Width="134"/>
<GroupBox Header="MidFielder" HorizontalAlignment="Left" Margin="278,0,0,0" VerticalAlignment="Top" Height="307" Width="134"/>
<GroupBox Header="GroupBox" HorizontalAlignment="Left" Margin="417,0,0,0" VerticalAlignment="Top" Height="307" Width="155"/>
</Grid>
</Border>
<ProgressBar BorderBrush="#FF6081B0" HorizontalAlignment="Stretch" Margin="2,303,0,43" Value="45" Grid.Row="2" Foreground="#FF6081B0" Grid.RowSpan="2" />
</Grid>
</StackPanel>
</Grid>
<ListBox Height="96" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Bottom" Name="listBox2" Width="782" Grid.RowSpan="2">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="30 0 30 0" />
</Style>
</ListBox.ItemContainerStyle>
<ListBoxItem Content="Vertical Item 1" />
<ListBoxItem Content="Vertical Item 2" />
<ListBoxItem Content="Vertical Item 3" />
<ListBoxItem Content="Vertical Item 4" />
<ListBoxItem Content="Vertical Item 5" />
</ListBox>
</Grid>
</Window>
Same answer as in this question. StackPanel will not respect stretch alignments in the same direction as its orientation. So a StackPanel whose orientation is vertical will not respect a VerticalAlignment of stretch for a child.
listBox1 doesn't stretch because it's VerticalAlignment is stretch and it's container StackPanel has an orientation of Vertical (that's its default). You could change that StackPanel to be horizontal, replace it with another container (such as a DockPanel), or remove it entirely since it only contains one element.
Similar reasoning can be applied to your other issues

Categories

Resources