Basically I'm getting some data from a service and displaying the results in a listbox. The template for the items is using a grid. NOTE: If there is a better way let me know.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"/>
<TextBlock Grid.Column="1"/>
</Grid>
The problem is, that sometimes an image is not returned. In that case the column for the image should collapse and the text column should take up the full width.
I've tried a couple of different ways already with no luck. How can I collapse this column when no image is returned?
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0"/>
<TextBlock Grid.Column="1"/>
</Grid>
Setting the image column width to auto will resize the column width according to the image size. If there is no image the size will be set to 0. The text column is set to *, this way it always takes all the available space.
Note: If your images are big, you may need to set MaxWidth as well.
You can use Expander control and set IsExpanded property.
Related
I have a grid that contains three columns.
<Grid Background="AliceBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="8*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="2*" Name="ManualControlsSplit" />
</Grid.ColumnDefinitions>
The first column contains a Grid and a chart.
The second column contains a GridSplitter.
The third column contains a StackPanel which contains a number of TextBlocks, Buttons and Grids containing TextBlocks and Buttons. Text size is dynamic and based on translation resources.
I need to calculate the minimum width that the contents of the third column would ideally like to be able to be drawn into so that the contents are not clipped.
My knowledge of WPF is limited to what I can google so any help would be appreciated.
With layout in WPF, you can allow one if not more of the Grid.Columns to be <ColumnDefinition Width="Auto"/>. This essentially tells WPF to allow as much space as the contained controls want. The use of Auto cascades too, so in StackPanel you refer to, you can make that controls width Auto as well, likewise with the items it contains; if the stack panel merely contains a TextBlock (via some template or whatever), then you can also set this width to Auto and the width with set itself according to the contained text.
<Grid Background="AliceBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="5"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
...
<StackPanel Grid.Column=2
Width="Auto">
<TextBlock Width="Auto"
Text="This is TextBlock"/>
...
</StackPanel>
...
</Grid>
In this case the Text of the TextBlock sets the width of the StackPanel, which in turn sets the width of the 3rd grid column.
I hope this helps.
My WPF XAML setup is as follows (bits removed to keep this simple):
<UserControl ....>
<Grid Background="AliceBlue" Name="TopGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="12*" Name="Graph" />
<ColumnDefinition Width="5" Name="GridSplitter" />
<ColumnDefinition Width="2*" Name="ManualControlsSplit" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Background="AliceBlue"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<!-- A Graph and simple controls -->
</Grid>
<!-- GRID SPLITTER -->
<GridSplitter Grid.Column="1" Width="5"
HorizontalAlignment="Stretch" Name="Splitter" />
<Label Grid.Column="1" Content="⁞" Foreground="White"
Background="DarkGray"
VerticalAlignment="Center" FontSize="26" FontWeight="Bold"
IsHitTestVisible="False"/>
<!-- end GRID SPLITTER -->
<StackPanel Grid.Column="2" Grid.Row="0" Margin="5"
Name="TemperatureControls">
<!-- Load of Controls -->
</StackPanel>
</Grid>
</UserControl>
To calculate the desired width I use the following code:
// get my UserControl object
var manualControlView = userControl as HeatingController.Views.ManualControlView;
// Query the current width of THIRD column
double actualWidth = manualControlView.ManualControlsSplit.ActualWidth;
// Set up a BIG size (this has to be bigger size than the contents of the
// THIRD column would ever need)
Size size = new Size(400, manualControlView.TopGrid.ActualHeight);
// Ask WPF layout to calculate the Desired size.
manualControlView.TemperatureControls.Measure(size);
double width = manualControlView.TemperatureControls.DesiredSize.Width;
if (actualWidth <= width)
{
// Too small - do something
}
else
{
// big enough - do something else.
}
The variable 'width' now contains the value I wanted to calculate.
I know that UniformGrid haven't attached properties ColumnSpan and RowSpan. But what i really need is container with fixed width and inner cells also with fixed widths, except few UIElements, that should be filled in few cells.
For example:
<UniformGrid Columns="4"> <TextBlock>1</TextBlock>
<TextBlock>2</TextBlock>
<TextBlock Grid.ColumnSpan="2">34</TextBlock>
UniformGrid is ideal for me except this situation: last TextBlock is not fill two cells.
Is it possible use some other solution to give the needed result?
Thank you for any advise!
P.S.And... why XAML parser is not stops with error where process this markup?
You could use a Grid with the columns having varying * widths:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<TextBlock>1</TextBlock>
<TextBlock Grid.Column="1">2</TextBlock>
<TextBlock Grid.Column="2">34</TextBlock>
</Grid>
I wanted use only XAML, but for now I still not found the answer. So, i've used following solution: placed all my elements in horizontal WrapPanel and set width for each element in code.
I am having some problems with a menu that is displayed as tabs (displayed vertically on the left side)
I have defined a headertemplate that defines a grid consisting of two columns where the first holds a textblock with the text retrieved via binding. The second column holds an image whose visibility is tied to a property - this image is used by validation and shown when data entered in another view has been validated.
The problem I have is getting the columns to share the same width. Example:
Text1| Image
MuchLongerText| Image
This looks a bit wonky and so am trying to get the Images to line up but can't seem to do this. The HeaderTemplate has a datatemplate specified as below
<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/> </Grid.ColumnDefinitions> <TextBlock Grid.Column="0" Text="{Binding Name}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
<Image Grid.Column="1" VerticalAlignment="Center" HorizontalAlignment="Center" Width="20" Height="20" x:Name="ValidationImage" Source="/Images/validationimage.bmp"/> </Grid>
I've tried putting it in a stackpanel and using sharedsize but no luck. Any help with this would be much appreciated!
Cheers
/Sakic21
Take a look at the Grid.IsSharedSizeScope and DefinitionBase.SharedSizeGroup properties.
in my Silverlight 4 App, I have a simple 3-columns Grid, that contains 3 Textblocks.
<Grid Background="{StaticResource BrushCharacteristicListBoxItemBackground}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="TextBlockCharacteristicName" Text="{Binding Property1}" HorizontalAlignment="Left" TextTrimming="WordEllipsis" ToolTipService.ToolTip="{Binding Text}" Margin="6,0,0,0" />
<TextBlock x:Name="TextBlockSeperator" Text="=" Grid.Column="1" />
<TextBlock x:Name="TextBlockCharacteristicValue" Text="{Binding Property3}" Grid.Column="2" HorizontalAlignment="Right" Margin="0,0,6,0" />
</Grid>
The width of the Grid depends on the containing user control. Now I want to cap the size of the first and the third textblock to the current size of their containing column, probably using MaxSize and bind it somehow to the size of the Column of the Grid.
Can anyone here tell me how to do this?
Thanks in advance,
Frank
By default the HorizontalAlignment property of the TextBlock is set to "Stretch" so it will fill the available size of the column its in, regardless of its content. Is that what you want?
Perhaps for some reason you do not want the TextBlock to be as wide as the Column it is in if its content does not need all the available space?
If so set the TextBlock.HorizontalAlignment to "Left". The TextBlock will then be only as wide as it needs to be until it reaches the width of the column, then its width will be constrained by the column.
I have this:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="50*" />
</Grid.ColumnDefinitions>
<GridSplitter Background="{x:Static SystemColors.ControlBrush}"
Grid.Column="1"
Margin="0,0,0,0"
Name="splitter"
HorizontalAlignment="Stretch" />
I'm trying to save and restore the splitter position. I'm using grid.ColumnDefinitions[0].Width, which returns the width of the column in pixels.
When I restore the position, how do I restore AND keep the 50* setting, so that when you resize the window, the column resizes correctly?
The Width property is not a simple double, it is a System.Windows.GridLength object which contains the Value property (double) and a GridUnitType property (GridUnitType) which is an enum.
So, to set your column's width to 50*:
grid.ColumnDefinitions[0].Width = new GridLength(50, GridUnitType.Star)
To save and restore all you need to do is to save the value and the GridUnitType for each column.
Hope it helps.