I am trying to bind Landscape and Portrait Images to the grid control. The Landscape images are loaded correctly, but I'm facing problems when it comes to load portrait images. Their bottom part is cut off(overflowed) so the grid row can't load the image with it's full Height. I tried setting the Row property with Height="Auto" or Height="*" but that didn't work.
Here is my XAML:
<ItemsControl ItemsSource="{Binding ItemsPrasanja}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock
Name="txtPrasanje"
Grid.Row="0"
Text="{Binding Tekst}"
TextWrapping="Wrap"/>
<Image Name="imgPrasanje"
Grid.Row="1"
Source="{Binding Slika}"
Margin="0,5,0,0"
/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
How can i solve this without setting manually Width or Height to the Grid or the Image control ?
P.S. The ItemsControl is part from another Grid control. It populates (Grid.Row="0") which I set to Height=" * "
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
You should look into the Stretch property of the Image object
A value of Fill will cause your image to stretch to completely fill the output area. When the output area and the image have different aspect ratios, the image is distorted by this stretching. To make an Image preserve the aspect ratio of the image, set this property to Uniform (default) or UniformToFill.
Related
My WPF Grid has 3 rows (Auto, *, *) and maxHeight set to 500. When there is no content for second or 3rd row, Grid still doesn't expand to its maxHeight.
XAML Code:
<Grid MaxHeight="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Button occupies 30 px-->
<Button Grid.Row="0" Content="SwitchGrid"/>
<ContentControl Grid.Row="1" Content="{Binding DG1}"/>
<ContentControl Grid.Row="2" Content="{Binding DG2}"/>
</Grid>
Problem Statement:
[Success] If both ContentControls are provided, they occupy equal space (~230 px) and Grid is shown to expand to MaxHeight=500 px.
[Failure] If either of the ContentControls are not provided, the other contentcontrol still occupies max ~230 px (this ContentControl can occupy 500 px, but due to Grid's restriction it occupies only 230 px and shows a scrollbar) and Grid doesn't expand to 500 px. Snoop reveals that one of the control control size is 0, but looks like Grid is still reserving space for it. I have seen this behavior even when the Grid is placed directly inside MainWindow, hence I dont this it is related to any other container.
What can I do to make sure Grid expands to MaxHeight if any of its children need it?
Thanks,
RDV
You can bind the row height to a string property..
<Grid MaxHeight="500">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Row1Height, FallbackValue=*}"/>
<RowDefinition Height="{Binding Row2Height, FallbackValue=*}"/>
</Grid.RowDefinitions>
<!-- Button occupies 30 px-->
<Button Grid.Row="0" Content="SwitchGrid"/>
<ContentControl Grid.Row="1" Content="{Binding DG1}"/>
<ContentControl Grid.Row="2" Content="{Binding DG2}"/>
</Grid>
Then you can update it whenever you want, for example..
public DG1 DG1 {
set{
// ..
Row1Height = value == null ? "0" : "*";
}
get{
// ..
}
}
I want the ScrollViewer to do only one thing - allow me to scroll. I don't want it to allow its Content to grow. Yet it does. How to prevent that?
<ScrollViewer VerticalScrollBarVisibility="Auto" >
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="a.png"/>
<Grid Grid.Row="1" Height="400"/>
</Grid>
</ScrollViewer>
If I comment out the ScrollViewer - the Image is small. If I leave the ScrollViewer - the Image grows. How to prevent that?
You would avoid stretching the Image by setting its Stretch property to None.
<Image Grid.Row="0" Stretch="None" .../>
The Grid and hence the Image element use the full width of the scrollable area. Since the default Stretch value is Uniform, the Image subsequently adjusts its height to keep its aspect ratio.
An equivalent, but simpler layout would be
<ScrollViewer VerticalScrollBarVisibility="Auto">
<StackPanel>
<Image Stretch="None" Source="a.png"/>
<Grid Height="400"/>
</StackPanel>
</ScrollViewer>
I'm developing an UserControl named Matrix2D to display 2 dimension matrix points in a x,y custom graphic.
Strange thing is, if I set Auto to Width/Height the columns/rows to the Grid that contains this Matrix2D control, like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<elem:Matrix2D x:Name="matrix2"
Grid.Row="0"
Grid.Column="0"
MaximumX="255"
MaximumY="127"
ZoomScale="1" />
</Grid>
I get the expected result (clean pixels):
I have also the expected result if I set HorizontalAlignment="Left" and VerticalAlignment="Top", like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<elem:Matrix2D x:Name="matrix2"
Grid.Row="0"
Grid.Column="0"
MaximumX="255"
MaximumY="127"
HorizontalAlignment="Left"
VerticalAlignment="Top"
ZoomScale="1" />
</Grid>
Although, If I don't set Auto to Grid neither set the Alignment, like this:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<elem:Matrix2D x:Name="matrix2"
Grid.Row="0"
Grid.Column="0"
MaximumX="255"
MaximumY="127"
ZoomScale="1" />
</Grid>
I get this blur result:
I already test several ways of developing this user control, with always the same result.
This is the current version:
<UserControl x:Class="Matrix2D"
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"
d:DesignHeight="300"
d:DesignWidth="300"
mc:Ignorable="d">
<Grid Background="White">
<Image x:Name="populationImg" Stretch="None" />
</Grid>
</UserControl>
In code behind:
I populate a WriteableBitmap and then I set populationImg.Source with it.
Already test the trick of setting RenderOptions.BitmapScalingMode="NearestNeighbor", but the result is approximate, and since this a Scientific Graphic I need that it be accurate. You can check in the corners of this result that is not accurate:
Even more visible in smaller graphic:
Setting RenderOptions.EdgeMode="Aliased" doesn't change anything.
Update
This explains why I have this blur effect:
To properly center an image, the container should have an even width,
height if the image's pixel width, height are even. If the image has
an odd pixel width, height, the containing element should also have an
odd width, height.
from Pixel Snapping in WPF Applications (In #Nicolas Repiquet answer)
Although, it didn't actually helped me to solve my problem. I would like that my user control be independent of its container. Any ideas how to do this?
My guess is that your control position within the parent container is not aligned to the pixel grid (ie, the x and y coordinates of your control on the screen is not a round number of pixels).
Try this :
<elem:Matrix2D SnapsToDevicePixels="true" ... />
UIElement.SnapsToDevicePixels Property
EDIT
"To properly center an image, the container should have an even width, height if the image's pixel width, height are even. If the image has an odd pixel width, height, the containing element should also have an odd width, height. " from Pixel Snapping in WPF Applications
I am trying to bind Landscape and Portrait Images to the grid control. The Landscape images are loaded correctly, but I'm facing problems when it comes to load portrait images. Their bottom part is cut off(overflowed) so the grid row can't load the image with it's full Height. I tried setting the Row property with Height="Auto" or Height="*" but that didn't work. Here is my XAML:
<ItemsControl ItemsSource="{Binding ItemsPrasanja}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock
Name="txtPrasanje"
Grid.Row="0"
Text="{Binding Tekst}"
TextWrapping="Wrap" />
<Image Name="imgPrasanje"
Grid.Row="1"
Source="{Binding Slika}"
Margin="0,5,0,0" />
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
How can I solve this without setting manually Width or Height to the Grid or the Image control?
P.S. The ItemsControl is part from another Grid control. It populates (Grid.Row="0") which I set to Height="*"
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
I already tried all the Stretch properties, but it didn't have any effect. The image is still croped.
Maybe you will show you'r full code and xaml of this control? Is it is ListBox, try to add this:
<phone:PhoneApplicationPage.Resources>
<Style x:Key="ListBoxItemStyle" TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
</Style>
</phone:PhoneApplicationPage.Resources>
ItemContainerStyle="{StaticResource ListBoxItemStyle}" to your control
Или просто покажи код всей контролы полностью
My group is building an editor-type app in WPF. One thing we noticed is that on my WinXP machine, running with the "windows classic style" theme, the text on buttons is fits fine. However on my friend's machine, who's running with the "windows xp style" theme, the font size is bigger so text on buttons get clipped at the bottom.
Is there a way to handle this nicely, like automatically resizing controls to fit the text?
I hesitate to manually resize the button to fit his layout as anyone else can have totally different settings through the Display Properties and Accessibility Options.
Thanks!
A WPF button will automatically resize to fit the content that it has been given, however it will only do this when it is inside a container that does not enforce size and its size has not been set manually. To prove this mess around with the font size in the following code snippet:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button
Grid.Column="1"
Grid.Row="1"
FontSize="24"
Content="QWERTY"/>
</Grid>
I guess that your buttons haven't resized because you have constrained them. To fix this you need to decide how you want them to resize (which can be very complicated when elements would overlap if they just grew blindly) and if none of the supplied panel types perform the growth behaviour that you are looking for then you may need to write your own that does.
Have you hardcoded element sizes using Width and Height properties? In WPF the recommended way to do this is to use the several layout containers.
The following is an example of a grid which lays two buttons at the bottom and a textbox at the top.
<Grid>
<Grid.RowDefinitions>
<!-- TextBox row with unspecified height. -->
<RowDefinition Height="*"/>
<!-- Button row with automated height so it resizes to
fit the content -->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Textbox on first row. -->
<TextBox Margin="3" Name="textBox1" Grid.Row="0" AcceptsReturn="True" />
<!-- StackPanel which lays the two buttons at the bottom horizontally.
RightToLeft is specified so that the first button appears on right.
-->
<StackPanel Grid.Row="1" HorizontalAlignment="Right"
Orientation="Horizontal" FlowDirection="RightToLeft">
<!-- The buttons. Only padding and margin are hardcoded so these
can resize to the contents -->
<Button Padding="3" Margin="3">OK</Button>
<Button Padding="3" Margin="3">Cancel</Button>
</StackPanel>
</Grid>