What I want to have:
a Grid-Splitter with 3 Columns
the MinWidth for all 3 Columns should work
the left and the right column should have a "defaultSize" like 100 and 200
when I resize the Form, only the column in the middle should resize. the columns on the left and on the right should stay the same size
if I add controls to the form, i want them to change their size according to the splitter
What I have:
I have a Grid with 3 Columns
the MinWidth for all 3 Columns works, but only with the ColumnWidth="*"
I dont know how to set a "DefaultSize" for the left and right column, because if I change the ColumnWidth, the MinWidth doesnt work anymore
when I resize the form, all 3 Columns change their size, not only the column in the middle
<ToolBarTray DockPanel.Dock="Top" IsLocked="True" Background="Pink">
<ToolBar Height="26" Background="Beige">
</ToolBar>
</ToolBarTray>
<StatusBar DockPanel.Dock="Bottom" Height="23" Background="Orange"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="50"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width ="*" MinWidth="100"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" MinWidth="50"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GridSplitter Grid.Column="1" Width="5" ShowsPreview="True" Background="Red" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
<GridSplitter Grid.Column="3" Width="5" ShowsPreview="True" Background="Red" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
</Grid>
Thanks so far :)
set the width (default size) for left and right column and it should be work
<Grid>
<StatusBar Height="23" Background="Orange" DockPanel.Dock="Bottom"/>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="50" Width="200"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition MinWidth="100" Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition MinWidth="50" Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GridSplitter
Width="5"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Background="Red"
ShowsPreview="True"/>
<GridSplitter
Width="5"
Grid.Column="3"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Background="Red"
ShowsPreview="True"/>
</Grid>
</Grid>
EDIT
here is a fix for the first grid maxwidth problem
<Grid x:Name="Root">
<Grid.Resources>
<local:MaxWidthConverter x:Key="MaxWidthConverter" />
</Grid.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="50"
Width="200"
MaxWidth="{Binding ElementName=Root, Path=ActualWidth, Mode=OneWay, Converter={StaticResource MaxWidthConverter}, ConverterParameter=260}" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition MinWidth="200"
Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition MinWidth="50"
Width="200" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<GridSplitter Width="5"
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Background="Red"
ShowsPreview="True" />
<GridSplitter Width="5"
Grid.Column="3"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Background="Red"
ShowsPreview="True" />
</Grid>
</Grid>
simple converter to calculate the maxwidth for the first column (260 = 200 minwidth + 50 minwidth + 5 splitter width + 5 splitter width
public class MaxWidthConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
double minWidth;
if (value is double && parameter is string && double.TryParse((string)parameter, NumberStyles.Any, CultureInfo.InvariantCulture, out minWidth)) {
var maxWidth = (double)value - minWidth;
return maxWidth < 0 ? 0 : maxWidth;
}
return 0;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return DependencyProperty.UnsetValue;
}
}
Related
I am using Syncfusion's SfDataGrid instead of standard one, but this question is more about XAML, not the control itself, I think.
So, I have a window with DataGrid. If there is for example 60 records, then the window gets really tall. I want the window not to change its size at all. And really don't know why it's happening.
This is my XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<StackPanel Margin="10,0,10,0" Grid.Row="0" DataContext="{Binding Info}">
<TextBlock Text="Amount:"/>
<sf:CurrencyTextBox Value="{Binding Amount}" Margin="0,0,0,10"/>
<!-- some other controls -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0" Style="{StaticResource LeftLabel}"
Text="Count:"/>
<sf:UpDown Grid.Column="1" Grid.Row="0" Margin="0,0,0,5"
Value="{Binding Count}"/>
<TextBlock Grid.Column="0" Grid.Row="1" Style="{StaticResource LeftLabel}"
Text="Year count:"/>
<sf:UpDown Grid.Column="1" Grid.Row="1"
Value="{Binding YearCount}"/>
</Grid>
</StackPanel>
<Button Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,10,10,5"
Content="Simulate >>"
Command="{Binding SimulateCommand}"/>
</Grid>
<!-- This is right part of the window with datagrid -->
<DockPanel Grid.Column="1">
<WrapPanel DockPanel.Dock="Top">
<TextBlock Margin="10" Text="Total amount:" />
<TextBlock Text="{Binding TotalAmount"/>
</WrapPanel>
<!-- and the datagrid -->
<sf:SfDataGrid AutoGenerateColumns="False"
AllowDeleting="False"
AllowEditing="False"
IsReadOnly="False"
AllowGrouping="False"
AllowFiltering="False"
ItemsSource="{Binding History}">
<sf:SfDataGrid.Columns>
<sf:GridDateTimeColumn DisplayBinding="{Binding Date}" MappingName="PaymentDay" HeaderText="Date"/>
<sf:GridCurrencyColumn DisplayBinding="{Binding Amount}" MappingName="PayAmount" HeaderText="Amount"/>
</sf:SfDataGrid.Columns>
</sf:SfDataGrid>
</DockPanel>
</Grid>
So what is wrong with it?
I have two textboxes with constant height, I want to vertically stack the textboxes and a grid. I tried with stackpanel but then the grid doesn't stretch and it stays with same size all the time (smallest as possible).
<StackPanel Orientation="Vertical" MaxWidth="110">
<TextBox Background="White" Height="40" Text="some text1"/>
<TextBox Background="White" Height="40" Text="some text2"/>
<Grid x:Name="internalGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MaxWidth="110"/>
<ColumnDefinition Width="1*" MaxWidth="110"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" MaxHeight="300"/>
<RowDefinition Height="1*" MaxHeight="300"/>
</Grid.RowDefinitions>
<Button Grid.Column="0" Grid.Row="0"/>
<Button Grid.Column="0" Grid.Row="1"/>
<Button Grid.Column="1" Grid.Row="0"/>
<Button Grid.Column="1" Grid.Row="1"/>
</Grid>
</StackPanel>
I also tried to use Grid instead of stackpanel but then when I make the app with full screen there is a margin between the textboxes and the internal grid
StackPanel doesn't behave like this. It occupies minimal required space. Use a Grid instead and define RowDefinitions. By default the space inside a Grid is equally distributed among the rows (Height is set to "*"), so you have to set the Height to "Auto" where you want the rows to occupy minimum space:
<Grid MaxWidth="110">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Background="White"
Height="40"
Text="some text1" />
<TextBox Grid.Row="1" Background="White"
Height="40"
Text="some text2" />
<Grid Grid.Row="2" x:Name="internalGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"
MaxWidth="110" />
<ColumnDefinition Width="1*"
MaxWidth="110" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"
MaxHeight="300" />
<RowDefinition Height="1*"
MaxHeight="300" />
</Grid.RowDefinitions>
<Button Grid.Column="0"
Grid.Row="0" />
<Button Grid.Column="0"
Grid.Row="1" />
<Button Grid.Column="1"
Grid.Row="0" />
<Button Grid.Column="1"
Grid.Row="1" />
</Grid>
</Grid>
Alternatively try a DockPanel:
<DockPanel MaxWidth="110" LastChildFill="True" >
<TextBox DockPanel.Dock="Top" Background="White"
Height="40"
Text="some text1" />
<TextBox DockPanel.Dock="Top" Background="White"
Height="40"
Text="some text2" />
<Grid DockPanel.Dock="Top" x:Name="internalGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"
MaxWidth="110" />
<ColumnDefinition Width="1*"
MaxWidth="110" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"
MaxHeight="300" />
<RowDefinition Height="1*"
MaxHeight="300" />
</Grid.RowDefinitions>
<Button Grid.Column="0"
Grid.Row="0" />
<Button Grid.Column="0"
Grid.Row="1" />
<Button Grid.Column="1"
Grid.Row="0" />
<Button Grid.Column="1"
Grid.Row="1" />
</Grid>
</DockPanel>
You can achieve this by using an IMultiValueConverter:
[ValueConversion(typeof(double), typeof(double))]
public class MyConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
var total = (double)values.FirstOrDefault();
var subtract = values.Cast<double>().Sum();
return total + total - subtract;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
You can introduce your converter in XAML in the resources section:
<Window.Resources>
<local:MyConverter x:Key="Converter"></local:MyConverter>
</Window.Resources>
And your XAML will be changed to:
<StackPanel Orientation="Vertical" MaxWidth="110" Background="Red">
<TextBox Name="Label1" Background="White" Height="40" Text="some text1"/>
<TextBox Name="Label2" Background="White" Height="40" Text="some text2"/>
<Grid x:Name="internalGrid" Background="Yellow" >
<Grid.Height>
<MultiBinding Converter="{StaticResource Converter}">
<Binding RelativeSource="{RelativeSource AncestorType=StackPanel}" Path="ActualHeight"/>
<Binding ElementName="Label1" Path="ActualHeight"/>
<Binding ElementName="Label2" Path="ActualHeight"/>
</MultiBinding>
</Grid.Height>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MaxWidth="110"/>
<ColumnDefinition Width="1*" MaxWidth="110"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*" MaxHeight="300"/>
<RowDefinition Height="1*" MaxHeight="300"/>
</Grid.RowDefinitions>
</Grid>
</StackPanel>
Definitely, the backgrounds colors are just for more clarification and not necessary.
I have a grid in my WPF application. This grid has two columns and one row.
Now, I am trying to align the first column content to the right and second column content to the left as below:
-----------------------------------------------------
| ProgressControlSpinner|"Loading..."|
-----------------------------------------------------
Instead I obtain:
-----------------------------------------------------
|ProgressControlSpinner|"Loading..." |
-----------------------------------------------------
Note that I want second column to be auto adjusted to the text width.
Also this grid should expand to the outer grid column in which it is contained.
My grid is as below:
<Grid x:Name="MyGrid" Grid.Column="1" Margin="3" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<controls:ProgressControlSpinner Grid.Column="0" Width="20" Height="20" HorizontalAlignment="Right"/>
<TextBlock Margin="3 0 0 0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Loading..." />
</Grid>
Note: This grid is contained within another outer grid.
I have solved. My problem was in the outer grid when defining the width for the column where inner grid was contained.
I had:
<Grid Grid.Column="0" Grid.Row="0" Margin="10 10 10 5" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid x:Name="MyGrid" Grid.Column="1" Margin="3" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<controls:ProgressControlSpinner Grid.Column="0" Width="20" Height="20" HorizontalAlignment="Right"/>
<TextBlock Margin="3 0 0 0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Loading..." />
</Grid>
</Grid>
and the correct is:
<Grid Grid.Column="0" Grid.Row="0" Margin="10 10 10 5" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid x:Name="MyGrid" Grid.Column="1" Margin="3" Visibility="Collapsed">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<controls:ProgressControlSpinner Grid.Column="0" Width="20" Height="20" HorizontalAlignment="Right"/>
<TextBlock Margin="3 0 0 0" Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Left" Text="Loading..." />
</Grid>
</Grid>
I have this xaml code:
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="640*" />
<ColumnDefinition Width="14"/>
<ColumnDefinition Width="350*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView Grid.Column="0" Grid.Row="2" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Visible" SelectionMode="Single" >
<ListView.ItemTemplate>
<DataTemplate>
<Border x:Name="border" BorderBrush="Black" BorderThickness="1" Margin="0,1,0,0">
<Grid Background="Transparent" VerticalAlignment="Center" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="300"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="*" MinWidth="300"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" MinHeight="150"/>
<RowDefinition Height="4"/>
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Stretch="UniformToFill" StretchDirection="Both">
<Image.Source>
</Image.Source>
</Image>
<TextBlock Grid.Column="0" Grid.Row="2" FontWeight="Black" TextAlignment="Center" >
<TextBlock.Text >
</TextBlock.Text>
</TextBlock>
<Image Grid.Column="2" Grid.Row="0" Stretch="UniformToFill" StretchDirection="Both" >
<Image.Source>
</Image.Source>
</Image>
<TextBlock Grid.Column="2" Grid.Row="2" FontWeight="Black" TextAlignment="Center" >
<TextBlock.Text >
</TextBlock.Text>
</TextBlock>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
when I resize the window that this xaml is on it, I can see that image are resize to fill the width, but they are not resized to fill the height. If the image is too big for the height, the top of image is shown and not the bottom section.
How can I change this xaml that when width or height is changes, the image size in the list view also changes?
See the documentation
UniformToFill preserves aspect
I think you want Fill
Stretch Enumeration
I'm trying to resize the textbox and the text inside of the textbox when the window is resized. I seem to be able to do one or the other, but not both at once.
Resizing the textbox works, but I can't resize the text inside:
Code for above example:
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="133*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Button Content="Button" Grid.Column="2"/>
<Button Content="Button" Grid.Column="1"/>
<TextBox TextWrapping="Wrap" VerticalContentAlignment="Center"/>
</Grid>
Or resizing the font works, but I can't make the textbox fill the viewbox I'm using:
Code for above example:
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="133*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Button Content="Button" Grid.Column="2"/>
<Button Content="Button" Grid.Column="1"/>
<Viewbox Stretch="Uniform">
<TextBox TextWrapping="Wrap" VerticalContentAlignment="Center"/>
</Viewbox>
</Grid>
Using Stretch="Fill" (on the right track, but I'd rather keep it uniform, and UniformToFill does something weird that I can't even see what's going on)
You can use converter.
public class FontSizeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
double actualHeight = System.Convert.ToDouble(value);
int fontSize = (int)(actualHeight * .5);
return fontSize;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
XAML:
....
<Window.Resources>
<local:FontSizeConverter x:Key="fontSizeCon" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="9*" />
<RowDefinition Height="1*" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="133*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Button Content="Button" Grid.Column="2"/>
<Button Content="Button" Grid.Column="1"/>
<TextBox TextWrapping="Wrap" VerticalContentAlignment="Center"
FontSize="{Binding Path=ActualHeight, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Grid}, Converter={StaticResource fontSizeCon}}"/>
</Grid>
</Grid>
...
Result:
Would something like this be suitable?
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="133*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Button Content="Button" Grid.Column="2"/>
<Button Content="Button" Grid.Column="1"/>
<Viewbox StretchDirection="Both" Stretch="Uniform">
<TextBox Text="some text"></TextBox>
</Viewbox>
</Grid>