I can see label have property FontAutoScalingEnabled
I tried to set it with different value and combination for other properties:
FontSize
MaxLines
HeightRequest
WidthRequest
My label is inside grid. I tried also to set heigh and width to int values insted of use *
Unfortunetly it never change size the font when don't fit in label.
How to use it?
My label is inside grid. I tried also to set heigh and width to int values insted of use *. Unfortunetly it never change size the font when don't fit in label. How to use it?
You can set Height and Width to Auto instead of Absolute or Star. And then set FontSize of Label:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Text="Row 0, Column 0"
FontSize="Large"
BackgroundColor="BurlyWood"/>
<Label Grid.Column="1"
Text="Row 0, Column 1 xx"
FontSize="Large"
BackgroundColor="Aqua"/>
<Label Grid.Row="1"
Text="Row 1"
FontSize="50"
BackgroundColor="Aqua"/>
<Label Grid.Row="2"
Text="Row 2, Column 0"
FontSize="Large"
BackgroundColor="BurlyWood"/>
</Grid>
I tested the code, and it works well. For more information, you can refer to Rows and columns by official.
Related
I have a seemingly simple use case but its been troubling me for hours
I have a grid with two rows and two columns, the first column should take all the available width and the second column should take the width it requires. The problem is with the 'required width' of the second column. This column contains a datagrid in the top row and a label (for simplicity) in the bottom row.
The datagrid has two columns which should both take up 50% width of the datagrid.
I want:
If the label is wider than the datagrid the datagrid should scale up (and NO semi column MAY appear at the end of the datagrid filling up the remaining space)
If the datagrid is wider than the label, the column may not be
smaller than the required size for the datagrid.
The problem:
If I set the datagrid columns to take all available space (width='*') it works if the label is bigger than the datagrid (but if the label is smaller the datagrid shrinks to the width of the label, and not al text is readable)
If I set the columns to 'autosize' it works is the label is smaller than the datagrid (but if the label is bigger the 'semi' column appears (and it really hurts my eyes)).
The code:
x:Class="WpfApp1.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:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="200" Width="400">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid Grid.Column="1" Name="grid">
<!-- Change column width to simulate the problemn-->
<DataGrid ItemsSource="{Binding Items}" ColumnWidth="*" RowHeaderWidth="0" Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType={x:Type Grid}}}"/>
</Grid>
<!-- change label text to simulate problemn-->
<Label Grid.Row="1" Grid.Column="1" Content="x"/>
</Grid>
The binding to the actual width of the grid is to have the columns scale up correctly
The Items is a List of objects (which contain two string values)
This is dirty and would probably cause me to rethink my design, but it works based on your requirements. I'm not sure how else to achieve this without creating a custom control or greatly modifying the DataGrid default template, but here goes.
Change your DataGrid styling to this and give names to both the Label and the DataGrid.
<DataGrid Name="dg" ItemsSource="{Binding Items}" CanUserResizeColumns="False"/>
///
<Label Grid.Row="1" Grid.Column="1" Content="x" Name="label"/>
Then create a ContentRendered event for your MainWindow.
Title="MainWindow" Height="450" Width="800" Name="mw" ContentRendered="Mw_ContentRendered">
Now in the render event, manually resize columns after the render occurs. You can't assign a star to the width as it won't resize correctly, so you need to divide your widths evenly base on column count.
private void Mw_ContentRendered(object sender, EventArgs e)
{
//Loop through columns and resize
for (int x = 0; x < dg.Columns.Count; x++)
{
double div = dg.ActualWidth / dg.Columns.Count;
double add = div - dg.Columns[x].ActualWidth;
if (add < 0) { div += -add; }
dg.Columns[x].Width = new DataGridLength(div);
}
}
EDIT: Updated width logic to account for uneven widths
I ended up creating my own user control.
This was relatively easy as I know at design time which rows I will have in the 'datagridview'.
Tronald's suggestion works, provided that the data does not change after rendering (mine does, both the datagrid contents and the 'label' change based on selections made in the rest of the application).
I still think that the 'Width="*" MinWidth="auto"' combination should be possible for a datagrid so If anybody has a solution.
I have a Grid that has some column defined and Column width is also defined in xaml.
<Border Grid.Row="2" BorderThickness="2" BorderBrush="#001732"
Width="{Binding ActualWidth, ElementName=ParentContainer}">
<Grid Name="DataGrid" Width="{Binding ActualWidth, ElementName=ParentContainer}"
Style="{StaticResource GridStyle}">
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
</Grid>
</Border>
now if i change the size of window the column width changes automatically. and i am trying to get the changed latest width with this code.
public void CoulmnWidthSetter()
{
_columnWidth = DataGrid.ColumnDefinitions[4].Width.Value;
foreach (var col in DataGrid.ColumnDefinitions)
{
_totalColumnsWidth = _totalColumnsWidth + col.Width.Value;
}
}
and calling the Column width setter method in below Event.
private void ParentContainer_OnSizeChanged(object sender, SizeChangedEventArgs e)
{
CoulmnWidthSetter();
}
or i have tried to call this method in Window size changed event also. But still it always give me that hard coded 50 width value why ?
In WPF Width and ActualWidth are two different things.
What you're looking for here is the ActualWidth of your ColumnDefinitions.
The ActualWidth is a double value that represents that length at that moment in time.
Signature:
public double ActualWidth { get; }
The Width is a GridLength type; that can be set by various means; including hard coded values, Star values, or Auto. You set the Width (a GridLength type) to give the ColumnDefinition the information needed to dynamically adjust itself accordingly or to remain constant. It is not intended to provide you with the current value but instead give the owner an expressive way of setting it's values.
Examples:
columnDefinition.Width = new GridLength(50); //Hard coded to 50
columnDefinition.Width = new GridLength(50, GridUnitType.Star); //dividend of remaining space allocated at 50.
//In other words; any other Star values will be divided in Width based on the remaining Grid size and the Star value given.
//A star value of 25* in another ColumnDefinition will make it half the length of the 50* and a value of 100* will make it twice the 50* or the 50* half of the 100*.
//Either way you look at it; the total remaining Width of the space provided by the panel gets divided out to the Star Columns and the dividend they get is based on their portion of the Star. 50* for all Columns will make them all equal.
columnDefinition.Width = GridLength.Auto; //Adjusts to the needed width dynamically. As your content grows so does the Width.
Width is also a DependencyProperty so it allows Binding and must be set on the UI thread.
Also; just a suggestion: You shouldn't need to set the size that way just because your view is dynamically changing size. This is what the * star is for in the value setting. There are also other means of doing this built in but without knowing exactly why you're doing it; have at it.
I have a view. The grid inside the view is divided into 2 columns.
<Grid x:Name="grdView">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
Inside the Auto column(Column 0), I have another view
<Border Grid.Column="0" Style="{DynamicResource BorderStyle}">
<Views:ViewerDataBrowser x:Name="dataBrowser" DataContext="{Binding ViewDataBrowserInstance}" />
</Border>
Inside this view I have a listbox and a data template defined for the list box.
Inside the data template I have 2 rows and 2 textblocks in each of them.
Issue
When the textblock characters are more than the width of the column, the listbox is being stretched and a scroll bar is also displayed. I don't want that to happen. I want the text to be truncated and show ... at the end.
I tried text trimming and text wrapping for the textblock. But it did not work. I also tried to set the width of data template to Auto, but it is not working. The only possible solution working for me is to set the width of the data template to a constant value.
I want the listbox to fit inside the grid and not show the scroll bar even though the text block have lengthy text. Please suggest a solution.
You can get and set the horiztonalScrollBar property of a listBox as described on the MSDN site. When setting the width of the listBox (pre-uwp) you may use device independent pixels (DIPs). Also, instead of using a constant, you may set the width proportional to that of the listBox's container--though not recommended vs DIPs and auto-resizing since certain dimensions behave better.
The issue is caused since the column width of the grid was set to "*".
When I changed the column width to constant, ie the same width as that of the parent, the issue seems to be fixed.
Regarding the truncation of the textblock, I set the textbox trimming property.
I recently experienced a strange behavior of text boxes.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="200"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="Test"/>
<TextBox Grid.Column="1" TextWrapping="Wrap" Text="testtesttesttesttesttesttesttesttesttesttest"/>
<Control Grid.Row="1" Grid.ColumnSpan="2" Width="280"/>
</Grid>
In this example code I have a Grid with 2 rows and 2 columns. The 2nd column is set to a fixed width. The TextBox has TextWrapping set to Wrap.
In the second row I have a Control with a fixed width that is higher than the Grid would normally be. This increases the ActualWidth of the second column from 200 to about 250.
The actual width of the TextBox also increases to match the new width of the column.
When I now add a long string to the text box the text, it doesn't use the full width of the TextBox but instead wraps way to early and leaves about 40 pixels at the end of the TextBox empty.
I've found out that the TextBox has a readonly ExtentWidth property. This property is responsible for the wrapping. In my example the values of the ExtentWidth is about 180, which is the 200 from the width of the grid column minus margins and paddings.
What can I do to fix the wrapping in the TextBox?
EDIT: This question is not a duplicate of Looking for explanation for WPF Grid ColumnSpan behavior.
That question explains what happens to the Widths of the grid columns. But it doesn't answer the question regarding the wrapping behavior of the TextBox.
I honestly don't understand the "why" part, but until someone provides a meaningful explanation, here are some workarounds:
Set an explicit width on the TextBox
Set MaxWidth on the column instead of Width
Bind the width of the TextBox to that of another element inside the same column. e.g:
<TextBox Grid.Column="1" Width="{Binding ActualWidth, ElementName=rect}" ... />
<Rectangle Grid.Column="1" x:Name="rect"/>
Note that the last one is the only usable workaround if you need to be able to change the column width at runtime and want the TextBox (and the wrapping) to change with it.
In a WPF application I have a textbox. I have set AcceptReturn to true
But I need to make the textbox bigger when the user clicks enter. What I mean is currently when the user clicks on the enter key, the cursor goes to a new line however the text box is still the same height and the above line is now hidden. Can I make the textboxHeight change dynamically depending on it's content?
Thanks
PS: I cannot use textarea I need to stay with the textboxes
I would suggest to keep it a current size and use the vertical scrollbar. But, if you're doing something that really requires it, place your TextBox into a Grid. Set the Grid row height to auto. Set the Height of the TextBox to Auto. Set the VerticalAlignment of the textbox to Stretch. In the code below I left the scrollbar settings in. You can change those how you see fit.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBox Grid.Row="0" x:Name="scriptTextBox" Margin="10" Height="Auto" Width="Auto" FontFamily="Consolas, Courier New"
HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
MaxLines="9999" AcceptsReturn="True" AcceptsTab="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Text="{Binding Path=Script, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
/>
</Grid>
You say you need to use Textboxes. Can you at least use an overriden Textbox? This worked pretty well in my testing:
public class AutoHeightTextbox : TextBox {
protected override Size ArrangeOverride(Size arrangeBounds) {
Size unboundSize = new Size(this.Width, double.PositiveInfinity);
Size textSize = base.MeasureOverride(unboundSize);
this.Height = textSize.Height;
return base.ArrangeOverride(arrangeBounds);
}
}