how to overflow element to be on top on another container? - c#

<Window x:Class="TestringWpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Background="Yellow"></StackPanel>
<StackPanel Grid.Row="1" Background="Green">
<Button Margin="0,0,0,10000000000">ABC</Button>
</StackPanel>
</Grid>
</Window>
The above code will gives me the situation below:
As you can see, the button was declared at the second StackPanel and hence no matter how I set the margin, the button couldn't go out of the green background. I'm wondering what can I do to declare the button in <StackPanel Grid.Row="1"> and appear partly on <StackPanel Grid.Row="0"> .
In conclusion, how to make an element overflow in it's container and overlap on another container? Is it possible?

Another option would be a RenderTransform.
<Button Content="ABC">
<Button.RenderTransform>
<TranslateTransform Y="-50"></TranslateTransform>
</Button.RenderTransform>
</Button>

Related

Textbox Filling all available space in Grid Row

I'm experiencing a problem with my UI XAML code. The problem is that I can't get my TextBox to fill in all available space in the Grid Row that contains it. I read quite a few posts about similar issues, and the summary of them is "don't use stack panel for this" and "set VerticalAlignment="Stretch"", but this did not work for me. Near the bottom of my XAML you can see the text box that I've been trying to get to stretch to fill the height of the grid row, along with the text box I'm hoping to have work by the end in a comment.
Having VerticalAlignment="Stretch" does not change the behavior of the XAML, and produces a one-line TextBox as if I didn't assign VerticalAlignment="Stretch" at all. This is what the GUI page looks like with or without VerticalAlignment="Stretch":
Here is the respective XAML code.
<ContentControl x:Class="Analytics.Configuration.UI.DataflowTemplateView"
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"
xmlns:local="clr-namespace:ComputersUnlimited.Analytics.Configuration.UI"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:core="http://schemas.cu.net/2011/xaml/presentation/core"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance local:DataflowTemplateViewModel, IsDesignTimeCreatable=True}">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" x:Name="Row0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Command="{Binding NavigateToPreviousControlCommand}" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="0,0,20,0">Back</Button>
<TextBlock Grid.Column="1" Text="M-Code Template Text" FontSize="20" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Grid>
<!--<TextBox Grid.Row="1"
TextWrapping="Wrap"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="0,6,0,6"
AcceptsReturn="True"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto"/>-->
<TextBox Grid.Row="1" VerticalAlignment="Stretch"/>
</Grid>
I've tried all the advice I've ran into with no success. So, if you have any advice, sharing would be appreciated.
Thank you.
Most likely there is an implicit style for TextBox that is setting a default Height. If that's the case, you'll need to set:
Height="NaN"
On your TextBox in order for it to stretch.

How to layout scrolling ListBox with auto max height and attach always visible Button below?

I want a layout where a ListBox is placed at the top of the window and a button is attached to the bottom of the ListBox. When the window is too small I want the ListBox to scroll and the button to be visible. When the window is too large, i.e. enough space for all controls and all list items, I want the ListBox to take up exactly as much space as it needs, and empty space be added below the button.
I have tried DockPanel:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="200" Width="525">
<DockPanel LastChildFill="False">
<ListBox Name="List" DockPanel.Dock="Top">
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
</ListBox>
<Button Content="Button" DockPanel.Dock="Top"></Button>
</DockPanel>
</Window>
But then the button is not visible when the window is too small.
I have tried Grid:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
Title="MainWindow" Height="200" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<ListBox Name="List" Grid.Row="0">
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
<ListBoxItem>Item</ListBoxItem>
</ListBox>
<Button Content="Button" Grid.Row="1"></Button>
</Grid>
</Window>
But when the window is larger than needed, the ListBox is stretched larger than its content instead of empty space being added below the button.
If I change the RowDefinitions to:
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
Then the Listbox does not scroll when the window is too small.
Any ideas?
try change Grid.VerticalAlignment. If it is set to Stretch (default value) and the window is larger than needed, the ListBox is also stretched because of Height="*".
<Grid VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
</Grid>

WPF GridSplitter not being hit-tested?

I seem to run into a strange problem with WPF GridSplitter.
If I do this:
<Window x:Class="WpfApplication20.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="102" />
<RowDefinition Height="1" />
<RowDefinition Height="192" />
</Grid.RowDefinitions>
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeDirection="Rows" Background="Black"></GridSplitter>
<Canvas Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="AliceBlue"></Canvas>
<Canvas Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Yellow"></Canvas>
</Grid>
</Window>
I can see the GridSplitter, but I cannot interact with it - mouse over it and cursor does not change and cannot resize rows with it.
Now if I change the order of the elements added to the grid:
<Window x:Class="WpfApplication20.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="102" />
<RowDefinition Height="1" />
<RowDefinition Height="192" />
</Grid.RowDefinitions>
<Canvas Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="AliceBlue"></Canvas>
<Canvas Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Yellow"></Canvas>
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeDirection="Rows" Background="Black"></GridSplitter>
</Grid>
</Window>
Then the GridSplitter is working fine.
Note that I put Panel.ZIndex="1" in the first case for the GridSplitter, it will also work.
Then I tried this (added UseLayoutRounding="True" to Window):
<Window x:Class="WpfApplication20.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" UseLayoutRounding="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="102" />
<RowDefinition Height="1" />
<RowDefinition Height="192" />
</Grid.RowDefinitions>
<GridSplitter Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ResizeDirection="Rows" Background="Black"></GridSplitter>
<Canvas Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="AliceBlue"></Canvas>
<Canvas Grid.Row="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Yellow"></Canvas>
</Grid>
</Window>
This gives me a strange behaviour: Initially the Gridsplitter is being drawn with a height of 2px (sub-pixel positioning? but all the grid rows are integer height). If I resize the rows upwards, GridSplitter continues to work. If I resize the rows downwards I will get to a point where GridSplitter is being drawn with a height of 1px and once I release the mouse I can no longer interact with the GridSplitter.
Questions:
Why does GridSplitter depend on Z-order to work in the first two cases?
Why does GridSplitter work "intermittently" in the third case?

Stretch height of nested ItemsControl

On MainWindow, I have an ItemsControl that I'm adding UserControls to, and said UserControl also contains an ItemsControl containing other UserControls.
The problem is that a lot of items in the second ItemsControl aren't showing because they go past the height of the UserControl as it appears on MainWindow.
How can I make sure the UserControls in the first ItemsControl always stretch enough to show all UserControls in their ItemsControl? For trial and error I tried stretching via a ItemTemplate but that didn't change a thing.
<Window x:Class="X.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="DataTemplate1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ItemsPresenter Grid.Row="0" Grid.Column="0" DataContext="{Binding}"/>
</Grid>
</DataTemplate>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ItemsControl Grid.Row="0" x:Name="ic" ItemTemplate="{DynamicResource DataTemplate1}"/>
</Grid>
</Window>
--
<UserControl x:Class="X.UserControl1"
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="113" Width="209">
<UserControl.Resources>
<DataTemplate x:Key="DataTemplate1">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ItemsPresenter DataContext="{Binding}"/>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="Label" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
<ItemsControl Grid.Row="1" x:Name="ic" Margin="0,36,0,0" ItemTemplate="{DynamicResource DataTemplate1}"/>
</Grid>
</UserControl>
--
<UserControl x:Class="X.UserControl2"
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="40" Width="64">
<Grid>
<Label Content="Label2" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
</Grid>
</UserControl>
Added from my above comment, which turned out to be the problem.
Your UserControls have Height and Width explicitly set, which means they won't automatically resize/stretch to accommodate the child controls as you desire.
Removing the Height (and ideally Width), should do the trick:
<UserControl x:Class="X.UserControl1"
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" />
<!-- Your Code -->
</UserControl>

Placing controls under User Control

I'm new to WPF, and I am creating a user control as follows:
<UserControl x:Class="WpfApplication3.MyUserControl"
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"
x:Name="MyUserControl2"
d:DesignHeight="300" d:DesignWidth="300" Background="Coral">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="a" Grid.Row="0"/>
<Button Content="b" Grid.Row="1"/>
<Button Content="c" Grid.Row="2"/>
<ContentPresenter Grid.Row="3"/>
</Grid>
This produces the following layout, when the orange area is the content preseter:
In the main window that uses the user control, I want to inject controls into the content preseter
<Window x:Class="WpfApplication3.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication3"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:MyUserControl>
<local:MyUserControl.Content>
<Button Content="d"/>
</local:MyUserControl.Content>
</local:MyUserControl>
</Grid>
I would expect the get the following layout:
but instead the entire user control gets overlapped by button d.
How do I manage to do so?
Try placing button itself in Main Window -
<Grid>
<local:MyUserControl/>
<Button Content="d"/>
</Grid>
OR
<Grid>
<Grid.Resources>
<DataTemplate x:Key="MyContent">
<Button Content="d"/>
</DataTemplate>
</Grid.Resources>
<local:MyUserControl/>
</Grid>
and in your User Control -
<ContentPresenter Grid.Row="3" ContentTemplate="{DynamicResource MyContent}"/>
I'm pretty sure that that won't work. When you set the content of MyControl to the button you're saying that the whole content of the user control should be the Button. I think you need to have a property on your user control then bind the contentpresenter to that.
So Something like MyUserControl.SubContent {get; set;} then you can bind the ContentPresenter to that.

Categories

Resources