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?
Related
Just faced with a following issue:
I've tried to resize my simpliest WPF app and noticed that controls are not responsive at all.
Note: I've tried symbiosis of various controls like Grid, WievBox, Canvas etc., to no avail.
here is XAML code, to be exact controls which I need to get resizable (responsive) correspondingly different resolutions (aspect ratios).
<Window x:Class="WpfApplication6.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:WpfApplication6"
mc:Ignorable="d"
Title="MainWindow" Height="768" Width="1024" MinHeight="768" MinWidth="1024" MaxHeight="1080" MaxWidth="1920" WindowStartupLocation="CenterScreen" >
<Grid>
<Ellipse HorizontalAlignment="Left" Height="100" Margin="576,278,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"/>
<Rectangle HorizontalAlignment="Left" Height="100" Margin="559,518,0,0" Stroke="Black" VerticalAlignment="Top" Width="100"/>
<Label x:Name="label" Content="Label" FontStretch="Normal" FontSize="24" HorizontalAlignment="Left" Margin="595,230,0,0" VerticalAlignment="Top" Height="43" Width="64"/>
<Button x:Name="button" Content="Button" FontSize="24" HorizontalAlignment="Left" Margin="720,427,0,0" VerticalAlignment="Top" Width="83" Height="38"/>
</Grid>
P.S. Such writers as Nathan and McDonald in their books are broadcasting that WPF that's you need for adaptive and responsive application making. However, I'm in doubts after couple of days of looking for solution. I think WPF not much went ahead in contrast with Windows Form at least in terms of adaptation and responsiveness of applications.
So could someone help me in that matter.
Thanks in advance!
Don't use Margin to position controls, use your grid properties like ColumnDefinition and RowDefinition with things values like Auto and *
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
Nice little tutorial
Use RowDefinition and ColumnDefiniton for your Grid control instead of using Margin to place your controls. Also replace the Height and Width properties for the Ellipse and Rectangle with Stretch.
<Window x:Class="WpfApplication6.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:WpfApplication6"
mc:Ignorable="d"
Title="MainWindow" Height="768" Width="1024" MinHeight="768" MinWidth="1024" MaxHeight="1080" MaxWidth="1920" WindowStartupLocation="CenterScreen" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Ellipse Grid.Row="0"
Stretch="Fill"
Stroke="Black" />
<Rectangle Grid.Row="1"
Stretch="Fill"
Stroke="Black" />
<Label Grid.Row="2"
x:Name="label"
Content="Label"
FontStretch="Normal"
FontSize="24" />
<Button Grid.Row="3"
x:Name="button"
Content="Button"
FontSize="24" />
</Grid>
</Window>
Thanks guys, of course, however it's not a solution. See screens below.
As you can see , all important to me controls "swam" to left.
I'm trying to reduce my window size to 70%, in which there will be an image that will be stretched for 100% width and 30% (below the image) height, in which there is a stack panel containing some controls.
<Window x:Class="CapManageR.Video"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Video" Height="500" Width="1000"
Loaded="Window_Loaded" Closing="Window_Closing">
<Grid Name="grid1">
<Image Source="c://a.png" HorizontalAlignment="Stretch" Height="700"></Image>
<StackPanel Height="300" HorizontalAlignment="Stretch">
<Slider x:Name="horizSlider"
Minimum="0"
Maximum="100"
Value="50"
LargeChange="10"
SmallChange="1"
Width="200"
Margin="186,356,406,51"
PreviewMouseUp="horizSlider_PreviewMouseUp"/>
</StackPanel>
</Grid>
</Window>
I don't really know how to solve this. The above is my code so far. It is not really working. Can someone help so it will be proportional even upon resizing?
<Grid Name="grid1">
<Grid.RowDefinitions>
<RowDefinition Height="70*" />
<RowDefinition Height="30*" />
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="c://a.png" Stretch="Fill" />
<StackPanel Grid.Row="1" >
....
</StackPanel>
</Grid>
I have the following example:
<Window x:Class="WpfOverlayTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="600">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Width="600" Height="200" Background="LightBlue">
<Grid Margin="0,125,0,0" Height="75" Width="200" Background="Red">
<Grid Margin="0,75,0,0" Background="Black" Height="20" Width="200" />
</Grid>
</Grid>
<Grid Grid.Row="1" Height="200" Width="600" Background="LightGreen" />
</Grid>
How can I make the Black Grid being displayed?
edit:
To make the Problem a bit more clear:
I Want to define the Black Grid inside the Red Grid, but it should be displayed over the Green Grid.
See the Red Grid as a UserControl and the Black Grid as a Menu Overlay.
Sometimes I see questions and answers here that I just can't believe. If you want to put two or more elements into one Grid.Row or Column, then just set their Grid.Row values to the same value. The lower the element is defined in the XAML, the further in front the element will be in the UI. So to add the black Grid on top of the green Grid, you can just do this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Width="600" Height="200" Background="LightBlue">
<Grid Margin="0,125,0,0" Height="75" Width="200" Background="Red">
</Grid>
</Grid>
<Grid Grid.Row="1" Height="200" Width="600" Background="LightGreen" />
<Grid Grid.Row="1" Background="Black" VerticalAlignment="Center"
Height="20" Width="200" /> <!-- This will be on top -->
</Grid>
UPDATE
It's pretty difficult to work out what you actually want, but after reading the comments, it seems as though you might want this instead:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Width="600" Height="200" Background="LightBlue">
<Grid Margin="0,125,0,0" Height="75" Width="200" Background="Red">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Background="Black" VerticalAlignment="Center" Height="20" Width="200" />
</Grid>
</Grid>
<Grid Grid.Row="1" Height="200" Width="600" Background="LightGreen" />
</Grid>
This is basic Grid stuff. I recommend the material in the Grid Class page on MSDN.
UPDATE 2
Now that you have provided a description of your problem in your question, I can finally provide the correct XAML for your requirements:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="0" Width="600" Height="200" Background="LightBlue" />
<Grid Grid.Row="1" Height="200" Width="600" Background="LightGreen" />
<Grid Grid.Row="1" VerticalAlignment="Center" Height="75" Width="200" Background="Red">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- This will be on top -->
<Grid Grid.Row="0" Background="Black" VerticalAlignment="Center" Height="20" Width="200" />
</Grid>
</Grid>
Set a RowDefinition on your Red grid and assign the Black Grid to it
<Canvas>
<Grid Width="600" Height="200" Background="LightBlue">
</Grid>
<Grid Margin="0,200,0,0" Height="175" Width="600" Background="LightGreen" />
<Grid Margin="200,125,0,0" Height="100" Width="200" Background="Red">
<Grid Margin="0,75,0,0" Background="Black" Height="20" Width="200" />
</Grid>
</Canvas>
EDIT: Added a screenshot
EDIT: Switched to a Canvas
<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>
Is there any way to make a silverlight/wpf grid stretch to its parent width/height (using auto) but do no expand to acommodate children? In a Silverlight application I have the following:
Main Page, with a Frame:
<ScrollViewer x:Name="LayoutRoot" BorderThickness="0" Padding="0" ScrollViewer.HorizontalScrollBarVisibility="Auto" ScrollViewer.VerticalScrollBarVisibility="Auto">
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Background="{StaticResource DefaultBackgroundBrush}" BorderBrush="{StaticResource DefaultBorderBrush}" BorderThickness="0,0,0,1">
<!--Some header content-->
</Border>
<sdk:Frame x:Name="Frame" Grid.Row="1" UriMapper="{StaticResource UriMapper}" ContentLoader="{StaticResource ContentLoader}" BorderThickness="0" />
</Grid>
</ScrollViewer>
In this frame I load the desired page:
<navigation:Page
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:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="MyNamespace.MyPage" mc:Ignorable="d"
d:DesignWidth="640" d:DesignHeight="480"
Title="{StaticResource PageTitle}">
<Grid x:Name="LayoutRoot">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel d:LayoutOverrides="Width" Visibility="Collapsed">
<!-- Some header content -->
</StackPanel>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock TextWrapping="Wrap" Text="Titletext" FontSize="13.333" FontWeight="Bold" d:LayoutOverrides="Height"/>
<RichTextBox BorderThickness="0" IsReadOnly="True" Background="{x:Null}" BorderBrush="{x:Null}" VerticalScrollBarVisibility="Auto" Grid.Row="1" Padding="0">
<Paragraph><Run Text="Text that will force the grid to expand."/></Paragraph>
</RichTextBox>
</Grid>
</Grid>
</Grid></navigation:Page>
The frame in the main page is designed to deal with its content overflow ( through the scrollviewer), because a I have some pages that demand a minimum size.
The grid that holds the text box stretches to the parent, but when I put a large text inside the text box the grid resizes to the width of the text, making the horizontal scroll bar of the frame's scrollviewer appear. I'm looking for a solution that doesn't require binding the max size of the grid to the max size of its parent ( this wouldn't work without hacks in Silverlight anyway, since binding to ActualWidth/Height is bugged). Any ideas?
You just have to change the wrapping like already posted AND change one property of the ScrollViewer:
ScrollViewer.HorizontalScrollBarVisibility="Auto"
to
ScrollViewer.HorizontalScrollBarVisibility="Disabled"