Resize Images inside grid - WPF - c#

I have to show three images in a way that center image should have double width of left or right end views. The Imagesource to Left and right end have size of 335x377 and the center imagesource have size of 403x226.
<Grid x:Name="LayoutRoot" Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" ></ColumnDefinition>
<ColumnDefinition Width="*" ></ColumnDefinition>
<ColumnDefinition Width="0.5*" ></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Grid.Row="0" Grid.Column="0" HorizontalAlignment="Center" Background="Blue" VerticalAlignment="Center" >
<Image Name="ImageViewer1" Stretch="None" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="1" HorizontalAlignment="Center" Background="Yellow" VerticalAlignment="Center" >
<Image Name="ImageViewer2" Stretch="None" />
</StackPanel>
<StackPanel Grid.Row="0" Grid.Column="2" HorizontalAlignment="Center" Background="Red" VerticalAlignment="Center" >
<Image Name="ImageViewer3" Stretch="None" />
</StackPanel>
</Grid
Shall I need to define the size of 'ImageViewer' to achieve this ?

Unless the image widths do not more or less exactly match the column widths, it is obviously wrong to set
<Image Stretch="None" ... />
You would either set
<Image Stretch="Uniform" ... />
to make the left and right images horizontally fill their columns, or
<Image Stretch="UniformToFill" ... />
to make them also fill the row height, but cut off a bit at their sides.
You could also remove the StackPanels:
<Grid>
...
<Image x:Name="ImageViewer1" Grid.Column="0" Stretch="UniformToFill" />
<Image x:Name="ImageViewer2" Grid.Column="1" Stretch="UniformToFill" />
<Image x:Name="ImageViewer3" Grid.Column="2" Stretch="UniformToFill" />
</Grid>

Related

Viewbox interfering grid columns horizontal alignment

I am using a Viewbox with Stretch set to Uniform in order to not distort the content when user switches between screen resolutions and scale in the OS.
Within the Viewbox I have a grid.
The grid has only 1 row and some columns.
<Viewbox StretchDirection="Both"
Stretch="Uniform"
HorizontalAlignment="Left"
VerticalAlignment="Stretch">
<Grid Focusable="True"
Height="Auto">
<Grid.ColumnDefinitions>
<!-- Animated image -->
<ColumnDefinition Width="Auto" />
<!-- Stack panel with icon and text -->
<ColumnDefinition Width="Auto" />
<!-- A vertical separator -->
<ColumnDefinition Width="Auto" />
<!-- A button -->
<ColumnDefinition Width="Auto" />
<!-- Empty dummy column to help distribute space correctly between columns so it will cause next columns to be horizontally right aligned. -->
<ColumnDefinition Width="*" />
<!-- Help button -->
<ColumnDefinition Width="Auto" />
<!-- Three dots button -->
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0"
Orientation="Horizontal"
Visibility="{Binding Path=IsAnimatedImgVisible, Converter={StaticResource BoolToVisibility}}">
<v:UserControlAnimatedImg x:Name="UcSpinner" VerticalAlignment="Center" HorizontalAlignment="Left"/>
<Label SnapsToDevicePixels="True"
RenderOptions.BitmapScalingMode="HighQuality"
VerticalAlignment="Center" HorizontalAlignment="Left"
Content="{Binding Path=StatusText}"/>
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal">
<Image
Margin="10,5"
Height="24"
Width="24"
MaxHeight="24"
MaxWidth="24"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Stretch="None"
SnapsToDevicePixels="True"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding Path=Icon}"/>
<Label
VerticalAlignment="Center"
HorizontalAlignment="Left"
Content="{Binding Path=StatusTxt}"
SnapsToDevicePixels="True"
RenderOptions.BitmapScalingMode="HighQuality">
</Label>
</StackPanel>
<Separator Grid.Column="2"
Margin="10,5,5,5"
Height="26"
Style="{StaticResource {x:Static ToolBar.SeparatorStyleKey}}">
<Button Grid.Column="3"
Height="Auto"
Width="150"
Command="{Binding ButtonOnClick}">
<StackPanel Orientation="Horizontal">
<Image
Height="24"
Width="25"
MaxHeight="24"
MaxWidth="25"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Stretch="None"
SnapsToDevicePixels="True"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding ImageIcon}"/>
<TextBlock
Margin="10,2,5,2"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Text="{x:Static p:Resources.BtnText}"
SnapsToDevicePixels="True"
RenderOptions.BitmapScalingMode="HighQuality">
</TextBlock>
</StackPanel>
</Button>
<!-- Empty dummy space to help distribute space correctly between columns and
make next columns to be horizontally right aligned. This column will be blank
space.-->
<ContentControl Grid.Column="4"/>
<Button
Grid.Column="5"
Height="25"
Width="25"
MaxHeight="25"
MaxWidth="25"
Margin="8,0,5,0"
Style="{StaticResource {x:Static ToolBar.ButtonStyleKey}}"
Command="{Binding BtnHlpClick}">
<Image HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
SnapsToDevicePixels="True"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding ImageHelpIcon}"/>
</Button>
<StackPanel Grid.Column="6"
x:Name="PlaceHolder"
VerticalAlignment="Center"
Margin="2,0,12,0"
Width="27"
Height="Auto">
<Image
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Uniform"
Height="20"
Width="20"
SnapsToDevicePixels="True"
RenderOptions.BitmapScalingMode="HighQuality"
Source="{Binding ImgThreeDotsIcon}">
<Image.ContextMenu>
<ContextMenu Placement="Bottom" Background="#FFFFFF">
<MenuItem Header="{x:Static p:Resources.mnutext}" Command="{Binding MenuOnClick}"></MenuItem>
</ContextMenu>
</Image.ContextMenu>
</Image>
</StackPanel>
</Viewbox>
The first column is shown or not depending on a condition. Here I will show you only the use case with the first column not visible.
Above code produces below result (first column not visible):
And what I want, the expected result would be:
I want the last two columns (5 and 6) horizontally aligned to the rightmost and an extra blank space between columns 3 and 5. Note that column 4 is used as a dummy column to make this extra blank space area and its width is set to "*" in columndefinitions.
How can I get the expected result? If I remove the Viewbox then I get the expected result but I want to get the same result with the Viewbox added. I need the viewbox as root, i don't want to remove it, because using it I make content to be independent of the screen resolution and scaling (Viewbox does it automatically).
I think you need an explicit width for your grid.
Or at least once I set that, things work better.
You've not shown us a minimal reproduction of your issue so I made one myself.
I used some rectangles for this.
Note there is fixed size for the grid so measure arrange knows how big everything should be in order for * to work.
</Window.Resources>
<Viewbox>
<Grid Width="700">
<Grid.ColumnDefinitions>
<!-- Animated image -->
<ColumnDefinition Width="Auto" />
<!-- Stack panel with icon and text -->
<ColumnDefinition Width="Auto" />
<!-- A vertical separator -->
<ColumnDefinition Width="Auto" />
<!-- A button -->
<ColumnDefinition Width="Auto" />
<!-- Empty dummy column to help distribute space correctly between columns so it will cause next columns to be horizontally right aligned. -->
<ColumnDefinition Width="*" />
<!-- Help button -->
<ColumnDefinition Width="Auto" />
<!-- Three dots button -->
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Rectangle Width="100" Height="50" Grid.Column="0"
Fill="Red" Margin="4"/>
<Rectangle Width="100" Height="50" Grid.Column="1"
Fill="Red" Margin="4"/>
<Rectangle Width="100" Height="50" Grid.Column="7"
Fill="Red" Margin="4"/>
</Grid>
</Viewbox>
If I choke down the size it still retains the proportions:
If I then take that width off the grid:
This picture is the same viewbox and 700 wide grid inside a 900px wide window

UWP XAML: Custom Brush to draw a progress bar as Grid background

I have a Universal Windows App with a UI like this:
A vertical grid defining an number of rows
Each row is a horizontal grid with a number of columns
I'd like each row to have a progress bar in its background as shown in this mockup:
I tried using a ProgressBar control with the Grid.ColSpan property set, but the progress bar is drawn above the text and buttons so that won't work.
My next idea was to use a Rectangle with a percentage width, but I don't think it's possible to specify a relative width.
My current idea is to implement a custom Brush that I can then set as Background property for each horizontal Grid, but I could not figure out how to do custom drawing inside my Brush implementation.
Sample XAML:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.Background>
<MyCustomBrush RelativeWidth="75%"/> ???
</Grid.Background>
<Button Content="{x:Bind ToggleSymbol, Mode=OneWay}" Grid.Column="0"></Button>
<Button Grid.Column="1" Content="Title"></Button>
<TextBlock Text="SubTitle" Margin="0,0,10,0" Grid.Column="3"></TextBlock>
<ProgressBar Visibility="Collapsed" Grid.Column="0" Grid.ColumnSpan="5" Value="75" Maximum="100" Background="Transparent" Foreground="Red"></ProgressBar>
</Grid>
Two solutions here: reorder your XAML and put your ProgressBar directly after your background definition and before your buttons. This will cause it to be drawn under the buttons (As XAML draws in the order it finds things in XAML files by default, so reordering the XAML results in things being drawn in different orders)
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.Background>
<MyCustomBrush RelativeWidth="75%"/> ???
</Grid.Background>
<ProgressBar Visibility="Collapsed" Grid.Column="0" Grid.ColumnSpan="5" Value="75" Maximum="100" Background="Transparent" Foreground="Red" />
<Button Content="{x:Bind ToggleSymbol, Mode=OneWay}" Grid.Column="0"></Button>
<Button Grid.Column="1" Content="Title"></Button>
<TextBlock Text="SubTitle" Margin="0,0,10,0" Grid.Column="3"></TextBlock>
</Grid>
Another solution is to set the Canvas.ZIndex attached property on the ProgressBar to -1.
<ProgressBar Canvas.ZIndex="-1" .... ></ProgressBar>
which will cause it to be drawn under the rest of the Grid's content, which be default will have a ZIndex of 0.
i don't know what you done , but what is the problem in getting this type of Design
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<ProgressBar BorderBrush="Transparent" BorderThickness="2" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" VerticalAlignment="Stretch" Background="Transparent" Foreground="LightCoral" Minimum="0" Maximum="10" Value="7" />
<TextBlock Grid.Column="0" Grid.Row="0" Text="▶ Title" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="50"/>
<TextBlock Grid.Column="3" Grid.Row="0" Text="▶ SubTitle" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="50"/>
<ProgressBar BorderBrush="Transparent" BorderThickness="2" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" VerticalAlignment="Stretch" Background="Transparent" Foreground="LightCoral" Minimum="0" Maximum="10" Value="5" />
<TextBlock Grid.Column="0" Grid.Row="1" Text="▶ Title" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="50"/>
<TextBlock Grid.Column="3" Grid.Row="1" Text="▶ SubTitle" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="50"/>
<ProgressBar BorderBrush="Transparent" BorderThickness="2" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" VerticalAlignment="Stretch" Background="Transparent" Foreground="LightCoral" Minimum="0" Maximum="10" Value="8" />
<TextBlock Grid.Column="0" Grid.Row="2" Text="▶ Title" VerticalAlignment="Center" HorizontalAlignment="Left" FontSize="50"/>
<TextBlock Grid.Column="3" Grid.Row="2" Text="▶ SubTitle" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="50"/>
</Grid>

Drag and Drop a control between grid cells within an Windows 10 Universal App

What I try to achieve is being able to drag an image from one cell and drop it into another cell in the same grid. This grid in xaml is defined as below:
<Grid Grid.Row="1" HorizontalAlignment="Center" AllowDrop="True" VerticalAlignment="Center" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Margin="10,10,10,10" CanDrag="True" Grid.Row="0" Grid.Column="0" Source="Assets\mock.png" Width="64" Height="64" DropCompleted="Image_DropCompleted"/>
<Image Margin="10,10,10,10" CanDrag="True" Grid.Row="1" Grid.Column="1" Source="Assets\mock.png" Width="64" Height="64" DropCompleted="Image_DropCompleted"/>
<Image Margin="10,10,10,10" CanDrag="True" Grid.Row="2" Grid.Column="2" Source="Assets\mock.png" Width="64" Height="64" DropCompleted="Image_DropCompleted"/>
</Grid>
When I drop an image from one cell to another, Image_DropCompleted is triggered, and I can use static function in Grid to set the row and column index.
So my questions is how to calculate these indexes from current mouse position?

Vertical and Horizontal ScrollBars are not working - WPF

I have the following code:
<DockPanel>
<Grid>
<Grid.ColumnDefinitions>
<!--This will make any control in this column of grid take 1/10 of total width-->
<ColumnDefinition Width="1*" />
<!--This will make any control in this column of grid take 4/10 of total width-->
<ColumnDefinition Width="4*" />
<!--This will make any control in this column of grid take 4/10 of total width-->
<ColumnDefinition Width="4*" />
<!--This will make any control in this column of grid take 1/10 of total width-->
<ColumnDefinition Width="1*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
</Grid.RowDefinitions>
<Border BorderBrush="Black" BorderThickness="1" Grid.Row="0" Grid.Column="0">
<StackPanel>
<Image Source="/SAMPLE;component/Images/1_Left.png"/>
<Image Source="/SAMPLE;component/Images/2_Left.png"/>
<Image Source="/SAMPLE;component/Images/3_Left.png"/>
<Image Source="/SAMPLE;component/Images/4_Left.png"/>
</StackPanel>
</Border>
<ScrollViewer Grid.Row="0" Grid.Column="1">
<Canvas Name="Canvas1">
<Image Name="LeftImage"/>
<Image Name="LeftIcon"/>
</Canvas>
</ScrollViewer>
<ScrollViewer Grid.Row="0" Grid.Column="2">
<Canvas Name="Canvas2">
<Image Name="RightImage"/>
<Image Name="RightIcon"/>
</Canvas>
</ScrollViewer>
<Border BorderBrush="Black" BorderThickness="1" Grid.Row="0" Grid.Column="3">
<StackPanel>
<Image Source="/SAMPLE;component/Images/5_Right.png"/>
<Image Source="/SAMPLE;component/Images/6_Right.png"/>
<Image Source="/SAMPLE;component/Images/7_Right.png"/>
<Image Source="/SAMPLE;component/Images/8_Right.png"/>
</StackPanel>
</Border>
</Grid>
</DockPanel>
Even though the "LeftImage" and "RightImage" are having more width and height, the scroll bars are not working. I cannot able to scroll to view the complete image. Any help ?
Thanks
Grid does not support scrolling functionality. If you want to scroll something you need ScrollViewer control. So place your grid within a ScrollViewer insted of DockPanel
<ScrollViewer HorizontalScrollBarVisibility="Visible" VerticalScrollBarVisibility="Visible">
//Your grid
</ScrollViewer>

How to maintain the aspect ratio of Grid in this case?

I am working on silverligth 5 and under a situation where I have 3 row in a grid.
frst contains some text second contains a Scrollviewer and the third one contains buttons.
I want something like that when i resize the grid (suppose make it smaller) then button(on row 3) must persist but the data inside the scrollviewer (row2) can become smaller(which can be further view by scrollviewer) whereas UIelement on first row also must persist like buttons.
Here is my try of code:
<Grid x:Name="LayoutRoot" Background="{StaticResource BGBrush_1}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="EOD" FontWeight="Bold" Foreground="Orange" Margin="10" VerticalAlignment="Center" />
<ScrollViewer x:Name="panelScrollViewer" Grid.Row="1" VerticalScrollBarVisibility="Hidden" Height="600">
<telerik:RadTreeView Name="RadTreeViewObj" VerticalAlignment="Center" Margin="50" Background="{StaticResource BGBrush_1}" BorderBrush="{StaticResource BGBrush_1}" ItemsSource="{Binding EODDataStepsCollection}" SelectionMode="Single" ItemContainerStyle="{StaticResource TreeViewItemStyle}">
<telerik:RadTreeView.ItemTemplate>
<telerik:HierarchicalDataTemplate ItemsSource="{Binding RelatedItems}">
// here are some UI elements
</telerik:HierarchicalDataTemplate>
</telerik:RadTreeView.ItemTemplate>
</telerik:RadTreeView>
</ScrollViewer>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="CancelButton" Content="Cancel" FontWeight="Bold" Command="{Binding ButtonCancelCommand}" Height="23" HorizontalAlignment="Left" Margin="30,10,10,10" Style="{StaticResource ButtonStyle_Blue}" VerticalAlignment="Bottom" Width="80" Visibility="{Binding IsValidateVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />
<Button Grid.Column="1" x:Name="ValidateButton" Content="Validate" FontWeight="Bold" Command="{Binding ButtonValidateCommand}" Height="23" HorizontalAlignment="Right" Margin="10,10,30,10" Style="{StaticResource ButtonStyle_Blue}" VerticalAlignment="Bottom" Width="80" Visibility="{Binding IsValidateVisible, Converter={StaticResource BooleanToVisibilityConverter}}" />
</Grid>
</Grid>
How to achieve this ?
Please see that second button is hidden behind. (only half visible). How to solve this ?
Change your rowdefinitions to this:
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
And remove the fixed Height from the ScrollViewer.
The first and last rows will be as small as possible, while the middle row will take up the remaining space.
To avoid the Buttons overlapping, you can position them like this:
<StackPanel Grid.Row="2" HorizontalAlignment="Right" Orientation="Horizontal">
<Button x:Name="ValidateButton" Content="Validate" FontWeight="Bold" Margin="10,10,30,10" VerticalAlignment="Bottom" Width="80"/>
<Button x:Name="CancelButton" Content="Cancel" FontWeight="Bold" Margin="30,10,10,10" VerticalAlignment="Bottom" Width="80" />
</StackPanel>
Note: This will right-align the Cancel button. (I have also placed it to the right of the Validate button)

Categories