Image height inside Stack Panel - c#

I'm designing a imaging gallery with Scroll Viewer and Stack Panel in WPF like the following:
<ScrollViewer x:Name="ShopsScroll" Grid.Row="1" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden">
<StackPanel x:Name="stackPanel" Margin="0" Orientation="Horizontal" Height="Auto">
<Image Source="Images/1F/L1_angesb.jpg"/>
<Image Source="Images/1F/L1_chanel.jpg"/>
<Image Source="Images/1F/L1_dior.jpg"/>
<Image Source="Images/1F/L1_gucci.jpg"/>
<Image Source="Images/1F/L1_LV.jpg"/>
<Image Source="Images/1F/L1_nike.jpg"/>
</StackPanel>
Since the image is large in size, I would like to resize them to fit the height of the StackPanel. However, when I set the value of height in StackPanel as "Auto", it just used the height of the image, not its parent ScrollViewer. If I set a fix value to StackPanel, the problem seems being fixed, but I need to use my application in different size of screen in full screen. Thus, it should adapt different size but not hard code a fix value.
How I I do it?

You could use an element binding to bind the height of your images to the height of the StackPanel element. Sorry I can't test this code right now, but try something like
<Image Source="Images/1F/L1_nike.jpg" Height="{Binding ElementName=ShopsScroll, Path=Height}" />
See MSDN documentation on the Binding.ElementName property.
This property is useful when you want to bind to the property of another element in your application. For example, if you want to use a Slider to control the height of another control in your application, or if you want to bind the Content of your control to the SelectedValue property of your ListBox control.

Try to set HorizontalAlignment = "Stretch" and VerticalAlignment = "Stretch" for stackpanel
In my opinion better to have ItemsControl with images in it in your case
<ItemsControl HorizontalContentAlignment="Stretch">
<Image Source="Images/1F/L1_angesb.jpg"/>
<Image Source="Images/1F/L1_chanel.jpg"/>
<Image Source="Images/1F/L1_dior.jpg"/>
<Image Source="Images/1F/L1_gucci.jpg"/>
<Image Source="Images/1F/L1_LV.jpg"/>
<Image Source="Images/1F/L1_nike.jpg"/>
</ItemsControl>
Hope this helps

Related

WPF: Listbox custom items unable to auto size

I have a listbox with dynamically added items which are custom user controls (PriceGroupControl).
I am trying to resize that custom user control based on the size of the parent, but it always has a fixed size not related to the size of the listboxitem as far as I can see and resizing just clips the control.
I am using a similar control in a grid and that resizes perfectly.
My page has a grid, the first row has a combobox, the second has the custom control that resizes and the third row has a scrollviewer with a listbox in it. Since the listbox items are quite large and dynamically added, I use the scrollviewer.
The reason why I use a listbox is that, because based on the selected item, the content of the custom control on the second row of the grid is updated.
In XAML:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="2*"/>
<RowDefinition Height="5*"/>
</Grid.RowDefinitions>
<StackPanel Margin="12" Grid.Row="0">
<ComboBox Name="comboBoxPriceGroups" ItemsSource="{Binding Groups}"
SelectedValuePath="GroupName"
Width="250" SelectionChanged="comboBoxPriceGroups_SelectionChanged">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding GroupDescription}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
<Frame x:Name="ModPriceFrame" NavigationUIVisibility="Hidden" Grid.Row="1" Margin="10"/>
<ScrollViewer Grid.Row="2" VerticalScrollBarVisibility="Auto">
<ListBox x:Name="PriceListBox" Margin="10" Background="{StaticResource BackgroundLightBrush}" BorderThickness="0" SelectionChanged="PriceList_SelectionChanged"/>
</ScrollViewer>
</Grid>
The way I bound my listbox content to the listbox is the following:
List<PriceGroupControl> priceGroupControls = new List<PriceGroupControl>();
foreach (GroupDetail detail in groupDetails)
{
priceGroupControls.Add(new PriceGroupControl(detail.GroupName, detail.GroupDetailDescription));
}
PriceListBox.ItemsSource = priceGroupControls;
I have tried the following:
listbox: width set to auto in XAML, width = double.NaN code behind
my custom control: horizontalAlignment = stretch, horizontalContentAlignment = stretch, width = double.NaN.
bind a list of listboxitems with each listboxitem having a pricegroupcontrol.
If I put an actual number e.g. 1000 as the minimum width of pricegroupcontrol, it sizes to this width and looks more normal (now everything is cramped together in the minimum space needed), but obviously doesn't resize with the screen.
I am fairly new to WPF, so maybe I am missing the obvious.
I have used the live visual tree to get an idea which part is causing the issue and this seems to indicate that it is the PriceGroupControl that is too small, while the listbox is the size of the screen.
Any help would be appreciated.

Overlay Grid on top of Image inside ScrollViewer

I have the following markup:
<ScrollViewer>
<StackPanel Orientation=Vertical>
<Image />
<Grid />
<ItemsControl />
</StackPanel>
</ScrollViewer>
Okay so the image is an animated loading gif. When an event is completed the program displays the grid and the items control as well, and the user is able to scroll up and down.
In order to do this currently I just set the image to Visiblity='Collapsed' and the Grid and the ItemsControl to Visible. How can I layer them so that the image is always underneath, and the grid and the items control are on top - so that when I fade out the grid and the items control the image appears underneath?
I know that there is an option for Z-Index, I tried placing the Image, Grid and ItemsControl inside a canvas and setting the Panel.ZIndex property but it didnt seem to work - for one when I set the opacity on the Grid to .5 I couldn't see the image underneath, and also the Grid didn't fill the space either (I need it to stretch to the size of the form).
This should work:
<ScrollViewer>
<Grid>
<Image/>
<StackPanel>
<Grid/>
<ItemsControl/>
</StackPanel>
</Grid>
</ScrollViewer>

WPF ScrollViewer is not working

I want to add scroll view to my program and I tried ScrollView control but that don't take effect. It's my first time dealing with scrolls please help me :).
My xaml Code:
<DockPanel Grid.Row="1" Background="#FF695887">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="795">
<Canvas Name="zemelapis" Height="Auto" Width="Auto">
<Image Name="pav_kelias" />
<Image Name="car1" />
</Canvas>
</ScrollViewer>
</DockPanel>
Because these 2 images is not fitting here I need a scroll for them. Maybe I should use ScrollBar?
My program example: https://gyazo.com/a4ba7e4d5004632e2229a87e686c4c09
, as you can see bottom image is not fitting in range of window.
You have specified Auto as Height and Width. This implies that the Canvas will fill the height available to it.
From the documentation:
Auto sizing behavior implies that the element will fill the height
available to it.
In this case the available height is the height of the ScrollViewer.
If you want the Canvas to be bigger, and hence the ScrollViewer to scroll, you should set a height on Canvas that is bigger than the height of ScrollViewer.
So, for example:
<DockPanel Grid.Row="1" Background="#FF695887">
<ScrollViewer VerticalScrollBarVisibility="Auto" Height="795">
<Canvas Name="zemelapis" Height="1000" Width="Auto">
<Image Name="pav_kelias" />
<Image Name="car1" />
</Canvas>
</ScrollViewer>
</DockPanel>
If you want your ScrollViewer to work easily, use a Grid instead of a Canvas:
<DockPanel Background="#FF695887">
<ScrollViewer >
<Grid Name="zemelapis">
<Image Name="pav_kelias" Source="acteurs.png"/>
<Image Name="car1" Source="public.jpg"/>
</Grid>
</ScrollViewer>
</DockPanel>
As explain by Domysee, Canvas gives you total control of the layout. Grid however will automatically adjust its size depending on the content.
See http://www.wpf-tutorial.com/panels/introduction-to-wpf-panels/

Centering a mediaelement according to the aspect ratio

So, I've got this mediaelement, which I want to appear in the middle of the screen, 20 pixels away from each edge, and when it's width gets to 600, it stops expanding and stays where it is. I've got the following XAML to get exactly what I want:
<Grid x:Name="video">
<MediaElement x:Name="player" AreTransportControlsEnabled="True" Margin="20,0" MaxWidth="600" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
The only problem is that the VerticalAlignment property seems to always be set to "Stretch". How can I fix this? I've tried using a viewbox, which works flawlessly, except I then get overly large or small TransportControls. I've also tried putting the mediaelement inside another grid with centered alignments, but I still get the same problem.
What you want is
20 pixels away from each edge.
But in your code you defined Margin="20,0", if you read the FrameworkElement.Margin property, you will find the useage <frameworkElement Margin="left+right,top+bottom"/>. With your code, this usage makes your MediaElement stretch in the vertical orientation.
If you use the Live Visual Tree to get a real-time view of your running XAML code, you will find, when you use the code Margin="20,0", the MediaElement is like this:
And if you use the code Margin="20", the MediaElement is like this:
The dashed red border in each picture stands for the MediaElement control.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Pivot Margin="0,0,0,0" Background="LightGray">
<PivotItem Header="Formulas">
<Grid>
<GridView HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Background="#FF983636">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<VariableSizedWrapGrid Orientation="Horizontal" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
<x:String>One</x:String>
<x:String>Two</x:String>
<x:String>Three</x:String>
<x:String>Four</x:String>
</GridView>
</Grid>
</PivotItem>
</Pivot>
</Grid>
The key here is HorizontalAlignment="Stretch" on the GridView.
The HorizontalAlignment="Center" on the VariableSizedWrapGrid inside the ItemsPanelTemplate inside the Gridview; should do the trick which will always keep the content centered regardless of the width of the screen.
In the end, I found how to fix this, by keeping a constant aspect ratio of 16/9:
XAML:
<Grid SizeChanged="player_SizeChanged" Background="Black" HorizontalAlignment="Center" VerticalAlignment="Center" MinWidth="1" MinHeight="1" Margin="30" MaxWidth="1000" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<MediaElement x:Name="player" Margin="0">
</Grid>
C#:
private void player_SizeChanged(object sender, SizeChangedEventArgs e)
{
(sender as Grid).Height = (e.NewSize.Width * 0.5625);
}

Issue with ScrollViewer in WPF

I am working on a WPF application and using a scrollViewer to view the content that is offlimit the screen area. Working fine, no issues.
But if my window contains a Listbox or Grid or anything like that and that control has many records then instead of adding a scrollbar to itself, it just increase the height of the control and window itself because scrollviewer believes it needs to extend.
I don't want to hardcode the listbox's height, because that make it same in different resolutions, i want to make it increase its height but not always as scrollviewer make it do so.
Thanks
You can't include a variable height/width object inside a ScrollViewer without setting the height/width of the viewer.
The scroll viewer effectively has infinite height so the grid expands to fill the "available" space - hence the effect you are seeing. As #JoeWhite says in his comments, the ScrollViewer is a container that can be as tall as it needs to be to hold all of its content. Anchoring wouldn't help - in effect, your ListBox already is anchored, it's just anchored to something that says "oh, I'll be whatever size you need me to be".
You'll need to either restrict the height, move the ListBox outside the ScrollViewer or use something other than a ScrollViewer.
Again quoting #Joe "These are the hazards of putting a scrolling area inside another scrolling area - it's poor usability and it's hard to define the behaviour."
You can wrap ScrollViewer into Grid, and bind scrollviewer's Width and Height properties to grid's ActualWidth and ActualHeight. So the scrollviewer will have fixed size equal to the size of the grid which will change when window resize.
Example:
<Grid x:Name="LayoutRoot" Background="White">
<Grid Background="#FFF1F1F1" Height="49" VerticalAlignment="Top">
<Button Content="Обзор" Margin="0,13,175.25,0" VerticalAlignment="Top" FontSize="14.667" HorizontalAlignment="Right" Width="95.147">
</Button>
<Label Content="{Binding DocPath, Converter={StaticResource FileNameConverter}, FallbackValue=Выберите файл, TargetNullValue=Выберите файл}" HorizontalAlignment="Left" VerticalAlignment="Top" Width="342.603" Margin="10,10,0,0" Height="33"/>
<Button Content="Загрузить данные" HorizontalAlignment="Right" Margin="0,13,10,0" VerticalAlignment="Top" Width="151.147" FontSize="14.667">
</Button>
</Grid>
<Grid x:Name="scrollBorder" Margin="10,54,10,10">
<ScrollViewer x:Name="LogScroller" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto"
HorizontalAlignment="Left" VerticalAlignment="Top"
Height="{Binding ActualHeight, ElementName=scrollBorder}" Width="{Binding ActualWidth, ElementName=scrollBorder}" >
<ItemsControl ItemsSource="{Binding Log}" />
</ScrollViewer>
</Grid>
</Grid>

Categories