How to avoid sizing grip overlap in Window - wpf

I made a WPF Window containing StatusBar with StatusBarItem and ProgressBar.
The Window has a property ResizeMode set to CanResizeWithGrip.
It shows the sizing grip properly, but it overlaps elements underneath:
How can I avoid this overlap? I can set right margin to the progress bar, but how large? I don't want to use any magic numbers or hardcoded values. It would be also nice to have this resolved purely in XAML.

You can change style for "Window" considering all wishes.
http://msdn.microsoft.com/en-us/library/aa969824(v=vs.110).aspx
or https://stackoverflow.com/a/8278917/3492412
Or can do something like this
<StatusBar VerticalAlignment="Bottom">
<StatusBarItem x:Name="statusbar" Background="Gray" HorizontalContentAlignment="Stretch">
<DockPanel>
<ResizeGrip DockPanel.Dock="Right" Visibility="Hidden" />
<ProgressBar Background="red" Height="20" Value="50" />
</DockPanel>
</StatusBarItem>
</StatusBar>

Related

Horizontal scrolling a row of ViewBox images in Xaml

I'm working on a UWP Windows 10 app with a XAML UI. One of my pages requires that images fill the height of the window (or screen in tablet mode) and uniformly scale as one long row of images from left to right (going off-screen). I've got this set up perfectly using ViewBoxes for the images inside of a StackPanel set to a Horizontal Orientation like so:
<StackPanel Orientation="Horizontal">
<Viewbox>
<Image Source="http://lorempixel.com/200/200/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/400/600/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/700/700/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/300/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/500/" />
</Viewbox>
</StackPanel>
The intention is for the images to flow off-screen with a horizontal scroll that allows the user to pan from left to right to see the gallery of images as one long row.
I've tried enabling HorizontalScrollMode on the parent StackPanel like so:
<StackPanel Orientation="Horizontal" ScrollViewer.HorizontalScrollMode="Enabled">
But this did not enable any scrolling at all.
I also tried to wrap everything inside of a ScrollViewer like so:
<ScrollViewer HorizontalScrollMode="Enabled">
<StackPanel Orientation="Horizontal">
<Viewbox>
<Image Source="http://lorempixel.com/200/200/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/400/600/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/700/700/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/300/" />
</Viewbox>
<Viewbox>
<Image Source="http://lorempixel.com/100/500/" />
</Viewbox>
</StackPanel>
</ScrollViewer>
But this completly breaks my ViewBox layout by shrinking all the images so they fit within a small portion of the screen and no longer fill the window/tablet height.
I've tried a number of other variations with similar results. Does anyone have some suggestions for solving this? Let me know if you need more info.
You do need a ScrollViewer to enable scrolling, although you might need to set a few properties to make it only scroll horizontally as mentioned in Windows 8 ListView with horizontal item flow
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollMode="Enabled"
ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.ZoomMode="Disabled"
Now the Viewbox is not the most controllable... control. You could try using the
SquareGrid panel from my toolkit instead of the Viewboxes. Maybe simplify it a bit. If that isn't enough - you could add some bindable properties that would update when the size of your window changes and bind the Width and Height of these images to these properties. Note that you can't use ActualWidth or ActualHeight because these don't raise change notifications on size changes.
<GridView x:Name="ImageGridView"
SelectedItem="{x:Bind ViewModel.SelectedLocation, Mode=TwoWay}"
Margin="10,0"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollMode="Disabled"
ScrollViewer.HorizontalScrollMode="Auto"
Grid.Row="4" Grid.ColumnSpan="5"
ItemsSource="{x:Bind ViewModel.CheckedLocations}"
ItemContainerStyle="{StaticResource PinsGridViewItemStyle}"
ItemTemplate="{StaticResource ImageOverlayGalleryFolderDataTemplate}" >
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid MaximumRowsOrColumns="1"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
This is my code to show 1 row of photos. You can adjust by the MaxiumRowsOrColumns. Also note that both HorizontalScrollBarVisibility and HorizontalScrollMode are present to custom as you want to.

How to control button layout in Xaml

Im having trouble controlling the exact layout of a button control with XAML.
It seems that whatever i do the button is of a minimum width.
I have a simple button with only a textblock inside the button. But the button has a lot of margin and padding that i cant seem to get rid of (i know of negative margins and padding).
The things i want to know is:
1. Why in the world was it designed this way.
2. what are the groundrules for controlling the exact layout of a button?
My code is as follows:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="80"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0"></StackPanel>
<Pivot Grid.Row="1">
<Pivot.Title>
<StackPanel Orientation="Horizontal" Margin="-15,-3,0,0" Background="red" Width="480">
<Button Background="Blue" x:Name="btnStudies" Click="btnMenuItem_Click" Width="20">
<TextBlock Text="Title" Foreground="White"></TextBlock>
</Button>
<Button Background="Green">
<TextBlock Text="Title" Foreground="White"></TextBlock>
</Button>
<Button Background="Blue" Click="btnMenuItem_Click">
<TextBlock Text="Title" Foreground="White"></TextBlock>
</Button>
<Button Background="Blue" Click="btnMenuItem_Click">
<TextBlock Text="Title" Foreground="White"></TextBlock>
</Button>
<Button Background="Blue" Click="btnMenuItem_Click">
<TextBlock Text="Title" Foreground="White"></TextBlock>
</Button>
</StackPanel>
</Pivot.Title>
</Pivot>
</Grid>
I want five buttons in a row but these are already too wide for the screen (windows phone). Changing the width doesnt seem to have any effect (why is it there).
The textBlock control within the button the button is as wide as the text on it, but i dont seem to have any control on the width of the button. In HTML you only have padding or margin when you define it but in xaml it just seems to be there and for me its unclear how to undo that.
*****EDIT*****
After reading Rachel's reply i decided to start from the ground up.
Using the code below i still have no control over how wide the button is because it uses a certain amount of padding that i cant seem to remove. The button has a width of about 110 when i define a width lower than that it doesnt change. Margins and paddings of 0 have no effect at all (dont want to use negative values just yet because that doesnt seem very intuitive). So the code below is very simple but still the button takes up an amount of space that i dont have any control over. I cant imagine a reason why it was designed this way.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="400" />
</Grid.ColumnDefinitions>
<StackPanel Width="300" Background="Red" HorizontalAlignment="Left">
<Button Background="Blue" HorizontalAlignment="Left" Width="100" Margin="0" Padding="0">
<TextBlock Text="Title" Width="Auto" HorizontalAlignment="Left" />
</Button>
</StackPanel>
</Grid>
The type and size of the parent panel containing the control affects the size/layout of the child controls.
In your case, you have a Grid as your parent panel, and a Grid defaults to taking up all available space. In addition, children placed inside the grid default to taking up all available space as well unless you specify otherwise.
So your <Pivot> is being assigned a width equal to Grid.Width, and Pivot.Title sounds like it's being assigned a width equal to Pivot.Width, and StackPanel is being assigned a width equal to Pivot.Title.Width... you get the picture.
To specify that a control should not take up all available space, specify a HorizontalAlignment or VerticalAlignment property to tell it what side of the parent panel to dock the item on.
For example
<Pivot Grid.Row="1" HorizontalAlignment="Left">
or
<StackPanel OWidth="480" HorizontalAlignment="Left" ...>
If you're new to WPF's layout system, I would recommend reading through the codeproject article WPF Layouts: A Quick Visual Start to quickly learn what the main layout panels are for WPF.

VerticalAlignment="Stretch" for label inside canvas doesn't work

How to use VerticalAlignment="Stretch" with a Label inside a Canvas? I'm trying to center the text "Cancel" in the button as in the code below. To use fixed height and width for the label isn't a desired option.
<Button Name="buttonCancel" Width="80" Height="40" IsCancel="True" Padding="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Canvas>
<Label Canvas.Top="0" Canvas.Left="0" Padding="0" FontSize="10">Esc</Label>
<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">Cancel</Label>
</Canvas>
</Button>
Use a binding to the Canvas's ActualWidth:
<Canvas>
<Label Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type Canvas}}, Path=ActualWidth}">...</Label>
</Canvas>
But as mentioned above, if you are interested in dynamic stretching layouts, the Canvas is not the ideal choice of control.
A Canvas does not perform any scaling layout of its contents; if you want to scale the contents, you could use Grid in this case, which will, by default, scale both Label elements to fill the Content space.
Assuming you need the canvas for other objects that are of a fixed nature, you could overlay the Canvas on a Grid, and then put the labels in the grid. You can put the labels before the canvas to make them background z-index (overwritten by canvas objects) or after the canvas to make them higher z-index (will overwrite canvas objects). For example:
<Button Name="buttonCancel" Width="80" Height="40" IsCancel="True" Padding="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid>
<Label Padding="0" FontSize="10">Esc</Label>
<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Center" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">Cancel</Label>
<Canvas>
<!-- Your Canvas content here -->
</Canvas>
</Grid>
</Button>
Repeating my solution from the comments, since (a) you really don't want a Canvas and (b) it sounds like this solved your problems, so I'll make it an answer where it will be more visible to others.
Canvas is meant for fixed-pixel-size layouts, which is probably the least common case. You should replace your Canvas with a Grid as shown below, so that both Labels are laid out dynamically (and independently) within the available space:
<Grid>
<Label Padding="0" FontSize="10">Esc</Label>
<Label VerticalAlignment="Center" HorizontalAlignment="Center">Cancel</Label>
</Grid>

How to add a border to the Text inside a TextBlock in WPF?

I am kinda new to WPF, dont know if the question is weird. I wanted to know if its possible to add a border around the text inside a textBlock.
EDIT:
As per suggestion I have tried both but without much success:
<Border BorderBrush="#FF0B232F" BorderThickness="2">
<TextBlock HorizontalAlignment="Left" Text="TextBlock" TextWrapping="Wrap" FontSize="36" FontWeight="Bold" Foreground="#FF88BCCD" OpacityMask="Black"/>
</Border>
and
<Label BorderBrush="#FF0B232F" BorderThickness="2,2,2,2" Content="TextBlock" FontSize="36" FontWeight="Bold" Foreground="#FF88BCCD" />
Am I doing something wrong here?
In such cases I use Label or TextBlock placed in Border.
Both your approaches are correct, however, if you have the textblock/label inside a grid (or any other container) declared as you have, its contents will stretch.
Try setting the VerticalAlignment and/or HorizontalAlignment to an appropriate setting (Top/Left, Center)..
something like this:
<Border BorderBrush="#FF0B232F" BorderThickness="2" VerticalAlignment="Top">
<TextBlock HorizontalAlignment="Left" Text="TextBlock" TextWrapping="Wrap" FontSize="36" FontWeight="Bold" Foreground="#FF88BCCD" OpacityMask="Black"/>
</Border>
Assuming that you are asking for a full size TextBlock with a border overlay within the bounds of the TextBlock you could wrap it in a Grid and draw the borders over the top of the TextBlock like this...
<Grid HorizontalAlignment="Left">
<TextBlock Text="TextBlock" TextWrapping="Wrap" FontSize="36" FontWeight="Bold" Foreground="#FF88BCCD" OpacityMask="Black" />
<Border BorderBrush="#FF0B232F" BorderThickness="2" />
</Grid>
Because we haven't specified the grid row and column on the TextBlock and Border objects the border overlays on top of the TextBlock.
if you just want to have a border around your textblock or any other control use :
<Border>
<TextBlock></TextBlock>
</Border>
you set border properties like color ,cornerradius ,thickness,...

Window sizing related to contents

I've got two sizing issue regarding a Window I've got. The basic layout is like this
<Window MaxHeight="{DynamicResource {x:Static SystemParameters.VirtualScreenHeight}}"
MaxWidth="{DynamicResource {x:Static SystemParameters.VirtualScreenWidth}}"
>
<StackPanel>
<DockPanel LastChildFill="False">
<StackPanel DockPanel.Dock="Left"
Orientation="Horizontal">
<!--Some buttons-->
</StackPanel>
<StackPanel DockPanel.Dock="Right"
Orientation="Horizontal">
<!--Some buttons-->
</StackPanel>
</DockPanel>
<ScrollViewer>
<WrapPanel x:Name="Container">
</WrapPanel>
</ScrollViewer>
</StackPanel>
</Window>
1) How do I made the Window not get smaller horizontally than the DockPanel's width?
2) How do I make the ScrollViewer be restricted to the limits of the Window? It is sizing itself to its contents, extending past the bounds of the Window.
It sort of used to work when I had
<Window><ScrollViewer/></Window>
, but I really don't want the DockPanel inside the scroller. In the current form, it is even forcing the Window to break its MaxHeight.
I would recommend you to use Grid with * Lenght instead of DockPanel and StackPanel.
Just get rid of those StackPanels. Replace them with Grids and you should be good. The layout logic of the StackPanel is such that it will give children as much room in a certain direction (perpendicular to the StackPanels orientation) as they ask for. That's why you're seeing the odd layout issues.

Resources