How to stretch the image of (1* 66 ) pixel - wpf

In a WPF Application using XAML,
I have 2 images, which needs to be oriented horizontally. One is of width 784 * 66 and other is 1 * 66.
while, design time, since my window is auto it shows properly, but during runtime, the window is of 1280 width... so, the image 1 * 66 should stretch and cover the rest (1280 - (784 + 1))
|________________________________|_|
should become
|________________________________|___________________________|
which means , my firstimage should have the same width (784) and the second image should stretch to cover the rest even though its only one pixel.
Please help me
<Grid HorizontalAlignment="Left" Height="66" Name="grdTopImages">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" MinWidth="1" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="66" />
</Grid.RowDefinitions>
<Image Name="imgClientPhoto" Grid.Column="0" Grid.Row="0" Source="/Honeywell.eHTMP;component/Resources/_left.gif"></Image>
<Image Name="imgExtraImg" Grid.Column="1" Grid.Row="0" Stretch="Fill" Source="/Honeywell.eHTMP;component/Resources/_right.gif"></Image>
</Grid>
Thanks
Ramm

You've got your column definitions the wrong way around. Should be:
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
This means the first column is as big as it needs to be, and the second column takes up whatever's left.

Related

WPF: Calculating the size of a Grid Column

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.

How to bind Font Size to variable Grid Size

I have a grid with 2 columns and 2 rows. A single character (Unicode U+2699) was placed inside the bottom right grid field. It looks like this:
I´d like the character to automatically adjust its font size to fit the grid field it has been placed in (in this case it should be bound to the height of the second grid row, but since in some cases it could be unclear if the height or the width of the grid is smaller, it would be also nice to know how to bind to the lowest of those 2 values).
My implementation so far is something like the following (I simplified it a bit for this example):
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition x:Name="heightToBind" Height="40"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="14*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button FontSize="{Binding ElementName=heightToBind, Path=Height.Value, Mode=OneWay}" Content="⚙" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" />
</Grid>
The problem here is, that it only works if the height is a fixed value inside the RowDefinitions. I want it to work with the following definition:
<Grid.RowDefinitions>
<RowDefinition Height="4*"/>
<RowDefinition x:Name="heightToBind" Height="*"/>
</Grid.RowDefinitions>
As a bonus question I´d also be interested why it might be that the character is placed too low so it is getting cut off at the bottom (I tried VerticalAlignment="Center" for the button but with no effect).
You can try using a ViewBox as the button's content:
<Button Grid.Row="1" Grid.Column="1">
<Button.Content>
<Viewbox StretchDirection="Both" HorizontalAlignment="Stretch">
<TextBlock Text="⚙" />
</Viewbox>
</Button.Content>
</Button>
A ViewBox can stretch and scale his child to fill all the available space...
You could try binding to the ActualHeight instead of the Height:
<Button FontSize="{Binding ElementName=heightToBind, Path=ActualHeight.Value, Mode=OneWay}"
Content="⚙" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" />
This should work.
The * on the grid definition means take the available space as the height so it's only determined when the page layout has been prepared for layout. If the height is either unset or changed then the real height is returned in the ActualHeight property.

Grid SharedSizeGroup - columns are bouncing, resizing in infinite loop

I need table with both horizontal and vertical header (simple PivotGrid). I have found some similar (or almost same) problems here, but no one give the solution. In XAML I have defined this structure:
<Grid x:Name="grdMain" Background="White" Grid.IsSharedSizeScope="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0" Grid.Column="1" x:Name="grdHorizontalHeader">
<!-- place for column definitions and header labels defined in code -->
</Grid>
<Grid Grid.Row="1" Grid.Column="0" x:Name="grdVerticalHeader">
<!-- place for column definitions and header labels defined in code -->
</Grid>
<Grid Grid.Row="1" Grid.Column="1" x:Name="grdContent">
<!-- place for column definitions and header labels defined in code -->
</Grid>
</Grid>
So both header consist of grid with some ColumnDefinitions (resp. RowDefinitions) and I need to size Header-ColumnDefinitions according to Content-ColumnDefinitions. I do it in code:
foreach (var row in myColumnSource)
{
// Content columns definitions
var cD = new ColumnDefinition();
cD.Width = GridLength.Auto;
cD.SharedSizeGroup = "ColumnSharedSizeGroup" + row.Value;
this.grdContent.ColumnDefinitions.Add(cD);
// Header columns definitions
var cD2 = new ColumnDefinition();
cD2.Width = GridLength.Auto;
cD2.SharedSizeGroup = "ColumnSharedSizeGroup" + row.Value;
this.grdHorizontalHeader.ColumnDefinitions.Add(cD2);
...
So Header-Column should share it's Width with Content-Column. But when I run the program, the columns are bouncing and resizing in infinite loop. Row's height sharing work fine. Where could be the problem?
EDIT only columns in header (grdHorizontalHeader) are resizing. Columns in grdContent have correct and stable width.
The Grid control's algorithm for auto-sizing can be finicky sometimes.
Have you tried setting a MinWidth on each of your columns/rows?
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="30" />
<ColumnDefinition Width="Auto" MinWidth="30" />
<ColumnDefinition Width="Auto" MinWidth="30" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="15" />
<RowDefinition Height="Auto" MinHeight="15" />
<RowDefinition Height="Auto" MinHeight="15" />
</Grid.RowDefinitions>
Not super elegant, but fixed this same problem for us.
If one grid has many SharedSizeGroup columns, the resulting layout performs an exponentially increasing number of passes to try and sort them out. Someone somewhere said Microsoft acknowledged the bug, but I couldn't find details of it.
To solve the issue, I broke my grid up into smaller grids inside a StackPanel. This made the layout fast again and retained the shared sizing.
As your grid is two dimensional, this would be harder. As you are adding controls dynamically, perhaps you could have one vertical StackPanel holding horizontal StackPanels holding smaller Grids?

WPF: Star in ColumnDefinition not expanding columns

I have a user control that need the 1st and 3rd column to have the same width at all time.
My code is a follows:
<UserControl x:Class="UserControls.ListBoxSelector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ListBox x:Name="ListBox_Source" Grid.Column="0" Grid.Row="0" />
<StackPanel Grid.Column="1" Grid.Row="0" Orientation="Vertical">
<Button Content=">" Click="Button_Add_Click"/>
<Button Content="<" Click="Button_Remove_Click" />
</StackPanel>
<ListBox x:Name="ListBox_Destination" Grid.Column="2" Grid.Row="0" />
</Grid>
</UserControl>
The result is not as expected as column 3 (ListBox_Destination) is not expanded at all.
Isn't the 5* in ColumnDefinition enough to force the 2 listbox to the same width??
UPDATED : Sorry that I forgot to mention that the problem only occurs when I put the control inside a RibbonGroup using Microsoft Ribbon for WPF
Sometimes, when you put your control in certian types of layout controls (like a StackPanel), it won't size as expected because the parent layout will only size the child to it's minimum desired size (just enough to show the content). This may be why you are seeing this when you put it in the RibbonGroup. Try giving your Grid a Width or MinWidth and see if that makes a difference.
yes it forces the columns 1 and 3 to be of the same size, but it doesnt gaurentee the content (listboxes) inside the colulms will be of the same size. You have to set the size of content to take up whole space

Image Stretch programmatically in WPF

In a WPF Application using XAML,
I created a stackpanel(width 1030) and I have 2 Images.
1. imgClient width = 784 Height = 66 and 2. imgClientExtra width =1 and Height = 66
imgClientExtra will be right end and imgClient will start at leftend.
so, the images will fit to 784 + 1 when the application is not running, the total image width is 785(784+1)..
but, wen the application is running.. the image has to stretch to 1030... with imgClientExtra will be at 1030 and imgClient will have to stretch to 1029 only..
I used stretch.fill ... but didn't work.
Currently I am using this way... is this needs to be modified?
<StackPanel Name="stkpnlHeader" Margin="0,0,0,0" Width="1254.662" Height="auto" HorizontalAlignment="Left" VerticalAlignment="Top">
<StackPanel Name="imgStkPnl"Orientation="Vertical" Width="1253.511" HorizontalAlignment="Left">
<Image Name="imgClientPhoto" HorizontalAlignment="Left" VerticalAlignment="Top" Width="784" Height="66"
Source="D:\ehtmp_top_left.gif" Stretch="Fill" StretchDirection="Both">
</Image>
<Image Name="imgExtraImg" Width="1" Height="66" Margin="0,-66,0,0" HorizontalAlignment="Right"
Source="D:\ehtmp_top_right.gif"
></Image>
</StackPanel> </StackPanel>
Change from a stackpanel to a Grid.
Set the Grid.Column definitions.
Create 2 column definitions
You can use Width to set a 'ratio' width.
For example, colA Width="5*" and colB Width="3*" means that colA gets 5/8 of the grid and colB gets 3/8 of the grid.
Combine this concept with also setting MinWidth and MaxWidth and you should be good to go.
Also, when setting widths in code, you often need to check an existing controls width by using the 'ActualWidth' property rather than 'Width' (which sometimes returns NaN).
I would think that a DockPanel in your case would work, since it automatically stretches the last element (I didn't try building this code so let me know if it doesn't work):
<DockPanel Height="66">
<Image Name="imgExtraImg" Source="D:\ehtmp_top_right.gif" DockPanel.Dock="Right"/>
<Image Name="imgClientPhoto" Source="D:\ehtmp_top_left.gif"/>
</DockPanel>
<Grid HorizontalAlignment="Left" Height="66" Name="imgGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="66"/>
</Grid.RowDefinitions>
<Image Name="imgClientPhoto" Grid.Column="0" Stretch="Fill"Source="D:\eHTMP\Exclusively_My_Work\UI_Application\Images\ehtmp_top_left.gif" ></Image>
<Image Name="imgExtraImg" Grid.Column="1"Source="D:\eHTMP\Builds\output\WPF_Example\UI_eHTMP\UI_eHTMP\Icons\ehtmp_top_right.gif"></Image></Grid>

Resources