I've got a grid (2x2) and Buttons inside of the grid.
I want to move a Button from cell(0,0) to cell (0,1) programmatically.
A: Does work (programmatically)
Move a Button from one grid cell to another grid cell.
B: Does NOT work (programmatically)
Move a Button inside of a StackPanel to a grid cell.
C: Does work (programmatically)
Move the whole StackPanel (with the Button inside) to another grid cell
What can I do?
<Window x:Class="CovidGamePrototype.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"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="1*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<StackPanel Name="stackPanel" Grid.Column="0" Grid.Row="0" Orientation="Vertical">
<Button Name="btnTopLeft1" Content="I am TopLeft 1" Height="Auto" />
<Button Name="btnTopLeft2" Content="I am TopLeft 2" Height="Auto" />
</StackPanel>
<Button Name="btnBottomLeft" Grid.Column="0" Grid.Row="1" Width="Auto" Content="I am BottomLeft" />
<Button Name="btnTopRight" Grid.Column="1" Grid.Row="0" Content="I am TopRight" />
<Button Name="btnBottomRight" Grid.Column="1" Grid.Row="1" Content="I am BottomRight"/>
</Grid>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
// does NOT work (move from left to right)
// this Button is inside of a StackPanel
Grid.SetColumn(btnTopLeft1, 1);
Grid.SetZIndex(btnTopLeft1, 5);
// works (move from left to right)
Grid.SetColumn(btnBottomLeft, 1);
Grid.SetZIndex(btnBottomLeft, 5);
// works (move from left to right)
// Grid.SetColumn(stackPanel, 1);
// Grid.SetZIndex(stackPanel, 5);
}
}
Remove the Button from StackPanel and insert the Button into the parent of the StackPanel which is a Grid in your case:
stackPanel.Children.Remove(btnTopLeft1);
var grid = (stackPanel.Parent as Grid);
grid?.Children.Add(btnTopLeft1);
Grid.SetColumn(btnTopLeft1, 1);
Grid.SetZIndex(btnTopLeft1, 5);
Related
In my wpf project I have one main window(Mainwindow.xaml) file and remaining all windows are user controls. If I click any menu of the mainwindow.xaml then the corresponding usercontrols will appear in the mainwindow.xaml form.
My requirement is, when the usercontrol window is resized, I need to resize all controls width (i.e textboxes,comoboxes,..etc). How can I achieve this.
First of all, the components you need to resize dynamically should not have fixed sizes. You should put everithing into Grid and set width/height to "Auto"/"x*"/ Alignment to stretch...
<UserControl ...>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/><!--2/5 of total height-->
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Grid.Row="1">Text </TextBlock>
<TextBox Grid.Column="2" >Enter</TextBox>
<TextBox Grid.Row="2" Grid.ColumnSpan="2">Button 5 Button 5 Button 5 Button 5</TextBox>
</Grid>
</UserControl>
Main
<Grid Width="Auto" HorizontalAlignment="Stretch">
<ContentControl ..." />
</Grid>
I wrote a simple WPF window that shows a customers grid.
in the bottom of the grid I added a button "Add a new Customer, but it blended into the background of the window, and I can't see it in View design.
this is the code:
<Window x:Class="NihulMlay._1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title=" Customers " Height="120" Width="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Button FontWeight="Bold">Customer name</Button>
<Button Grid.Column="1" FontWeight="Bold">Name</Button>
<Label Grid.Row="1"></Label>
<Label Grid.Column="1" Grid.Row="1"></Label>
<Button Grid.ColumnSpan="2" Content="Add a new Customer" HorizontalAlignment="Left" Height="100" Margin="270,114,0,-173" Grid.Row="1" VerticalAlignment="Top" Width="75"/>
</Grid>
</Window>
thanks.
Your Problem is the Window height of 120, once you resize it to say 350, you can see the Button.
The margin on your Button is:
Margin="270,114,0,-173"
which makes a Top-Margin of 114, the Button height is 100 and the row above is set to 40. This values alone would make a total required height of 254 to see all contents.
I think you are mistaking a Grid with a DataGrid. Grid is an area that contains other controls while DataGrid Represents a control that displays data in a tabular form. Looking at your code sample, I think DataGrid is what you wanted.
Assuming you did really mean Grid, then you can move your Button out by placing the entire Grid in another container (e.g. a DockPanel) like this:
<DockPanel>
<Button DockPanel.Dock="Bottom" Content="Add a new Customer" Height="100" Width="139"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" />
<ColumnDefinition Width="300" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40" />
<RowDefinition Height="40" />
</Grid.RowDefinitions>
<Button FontWeight="Bold">Customer name</Button>
<Button Grid.Column="1" FontWeight="Bold">Name</Button>
<Label Grid.Row="1"></Label>
<Label Grid.Column="1" Grid.Row="1"></Label>
</Grid>
</DockPanel>
I cannot seem to get my Grid right. I need a layout with two rows, the first row has a dynamic height based on a child grid's height. The second row contains a couple of Buttons, this row has a constant height of 30 pixels. When the content of the child grid has not yet reached a height of 842 pixels, the window should compress to fit the content. Otherwise, it expands based on the child Grid's height.
If the content of the child grid reaches 842 pixels, I wanted to display a scroll bar only for the first Grid row.
I have played around with MinHeight and MaxHeight but nothing has worked so far. Right now, the scroll bar appears far too late and the window doesn't compress when there is no content in the child grid.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition MaxHeight="35px" Height="35*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Row="0" Grid.Column="0" VerticalScrollBarVisibility="Auto" MinHeight="842px" Margin="0,0,0,13" Grid.RowSpan="2">
<Grid>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
</Grid.RowDefinitions>
//Many controls here...
</Grid>
</ScrollViewer>
<Button Grid.Column="0" Grid.Row="1"></Button>
<Button Grid.Column="0" Grid.Row="1"></Button>
</Grid>
EDIT: Added a picture for clarification.
Like this?
<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" SizeToContent="WidthAndHeight">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<ScrollViewer Background="Yellow" Grid.Row="0" VerticalScrollBarVisibility="Auto" MaxHeight="842" Margin="0,0,0,13">
<Grid>
<Rectangle Fill="Red" Width="100" Height="300" HorizontalAlignment="Center" VerticalAlignment="Center"></Rectangle>
</Grid>
</ScrollViewer>
<Button Grid.Row="1">But</Button>
</Grid>
</Window>
I have a simple WPF form with next XAML
<Window x:Class="ReikartzDataConverter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="650" Width="800">
<Grid Width="780" Height="650">
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="500"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
<Label Grid.Row="0" Content="Process information" Height="28" HorizontalAlignment="Left" Margin="0,20,0,0" Name="label1" VerticalAlignment="Top" Width="235" />
<DataGrid Grid.Row="1" Width="780" Height="500" Name="paysTable">
</DataGrid>
<Label Grid.Row="2" Height="28" Name="lblError" VerticalAlignment="Top" Visibility="Hidden" Foreground="OrangeRed" FontWeight="Bold" FontSize="12" />
<Button Grid.Row="3" Content="Quit" Height="23" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<Button Grid.Row="3" Content="Start" Height="23" Name="button2" VerticalAlignment="Top" Width="75" Click="button2_Click" />
</Grid>
</Window>
Why my 2 buttons from Grid.Row="3" are partially located out of the visible part of the window?
My window has the height="650" and my Grid also has the Height="650"
I have 4 Rows: 50, 50, 500, 50. So the last row must be located inside the window. Why is not so?
The Window Height of 650 also includes the 'chrome', i.e. the bar at the top of the window with the minimize, maximize buttons. It is a much better approach to create a layout which does not rely on a specific height. In your case, I would make the row that contains your grid auto-sized:
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition Height="50"></RowDefinition>
</Grid.RowDefinitions>
Then you can remove the height / width from your Grid, and all your other UI elements, just let the grid dictate the size of its children.
#ColinE's answer is the right approach in that you should adopt a "fluid" layout in WPF, but if you really want a fixed height for your content and you need the window to be the right size, you can use the SizeToContent property:
<Window x:Class="ReikartzDataConverter.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Width="800"
SizeToContent="Height">
<Grid Width="780" Height="650">
...
</Grid>
</Window>
Setting SizeToContent to "Height" will make the window resize vertically so that its contents fit. Don't forget to remove the Height property from the Window declaration.
I have the following simpl WPf grid, two columns, a button in each column, the first column auto sized and a splitter to allow column resizing.
An event handler is set up on the splitter MouseDoubleclick event. When the splitter is doulble clicked the button in the left column is collapsed.
Now, as column 1 is auto sized and the content is collapsed I would expect at this point that column 1 should effectively be hidden, however it is not.
Although its content is collapsed the column size does not change (remeber column is autosized).
Seems strange to me, I'd like the column to collapse - any idea what's happening here?
<Window x:Class="KingLayout.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Button x:Name="leftButton">Left</Button>
<Button Grid.Column="1" Margin="5,0,0,0">Right</Button>
<GridSplitter Name="verticalSplitter" ShowsPreview="True" Grid.RowSpan="1" Grid.Column="1" HorizontalAlignment="Left"
VerticalAlignment="Stretch" Width="5" MouseDoubleClick="verticalSplitter_MouseDoubleClick"/>
</Grid>
</Window>
private void verticalSplitter_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
leftButton.Visibility = leftButton.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
}
What's happening is that when you resize the column/row width/height with the GridSplitter, it sets the ActualHeight (or ActualWidth) of the column/row.
You should use a trigger to set row's height to auto (or zero) when your control is collapsed.
Get me updated with this.
In my case, I was able to use StackPanels and setting the Visibility="Collapsed" which caused it to properly resize.
<StackPanel Orientation="Vertical" Margin="5">
<StackPanel Orientation="Horizontal">
<!-- Some controls -->
</StackPanel>
<StackPanel Orientation="Horizontal" Visibility="{Binding YourVisibilityProperty}">
<!-- Some controls -->
</StackPanel>
</StackPanel>
It's because the splitter keeps its position in the grid, it pulls the first column, why don't you try an expander?
<Grid ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Expander ExpandDirection="Left">
<Button x:Name="leftButton">Left</Button>
</Expander>
<Button Grid.Column="1" Margin="5,0,0,0">Right</Button>
</Grid>