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

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)

Related

WPF fixed rows are resizing

I'm new in WPF and I try to creat specific UserControl to display data for a single product. I used Grid inside UserControl. So I create 5 columns and 3 rows. I want ot make 4 columns fixed (image, green-clored, blue-colored and column with controls) and last column (orange-colored) to fill all availabel space. Here my XAML and few screenshots:
<Grid Margin="0,0,0,5" Background="#FFDCD9D9" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="70" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.Row="0" Grid.RowSpan="4" Source="{Binding ItemThumbnailUrl}" Stretch="None" HorizontalAlignment="Right" Margin="5,0" />
<StackPanel Grid.Column="1" Grid.Row="0" Grid.ColumnSpan="4" Background="#FFDA6F6F">
<Label BorderThickness="0" Content="dsgsdgsgsgsdgsdg sd " FontSize="13.333" FontWeight="Bold" HorizontalAlignment="Left" />
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="1" Orientation="Horizontal" Background="#FF517823" HorizontalAlignment="Left" Width="70">
<Label Content="{Binding ItemPrice}" HorizontalAlignment="Left" FontSize="9.333" Width="45" />
<Label Content="грн." HorizontalAlignment="Left" FontSize="9.333" Width="25"/>
</StackPanel>
<StackPanel Grid.Column="2" Grid.Row="1" Orientation="Horizontal" Background="#FF214299" HorizontalAlignment="Left" Width="70">
<Label Content="{Binding Quantity}" HorizontalAlignment="Left" FontSize="9.333" Width="45" />
<Label Content="шт." HorizontalAlignment="Left" FontSize="9.333" Width="25"/>
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="2" Orientation="Horizontal" Background="#FF88B91E" HorizontalAlignment="Left" Width="70">
<Label Content="1С" HorizontalAlignment="Right" FontSize="9.333" Foreground="#FF8B8888" Width="45"/>
<Label Content="грн." HorizontalAlignment="Right" FontSize="9.333" Foreground="#FF8B8888" Width="25"/>
</StackPanel>
<StackPanel Grid.Column="2" Grid.Row="2" Orientation="Horizontal" Background="#FF228CBD" HorizontalAlignment="Left" Width="70">
<Label Content="1С" HorizontalAlignment="Right" FontSize="9.333" Foreground="#FF8B8888" Width="45"/>
<Label Content="шт." HorizontalAlignment="Right" FontSize="9.333" Foreground="#FF8B8888" Width="25"/>
</StackPanel>
<CheckBox Grid.Column="3" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Button Grid.Column="3" Grid.Row="2" Background="{x:Null}" Content="Редакт." Foreground="#FF444343" Width="50" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Label Grid.Column="4" Grid.RowSpan="2" Grid.Row="1" Background="#FFE08212" HorizontalContentAlignment="Stretch" />
</Grid>
If I have "Title" text (in red-colored cell) less than sum of 3 my fixed columns, everything is OK, but if a text larger I have problems with some paddings between columns (please see pictures)
So how can I resolve this problem?
I could reproduce your issue in a variety of cases when a Grid is used in a DataTemplate. I removed the StackPanel and used a TextBlock, then a a TextBlock hosted in a separate Grid, but all with the same result. I guess something is going wrong when WPF is determining the required size. I have often occurred this kind of strange behaviour in Grids (when part of an ItemTemplate). If you need a quick workaround then this should do the trick
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="80" MaxWidth="80" />
<ColumnDefinition MinWidth="70" MaxWidth="70" />
<ColumnDefinition MinWidth="70" MaxWidth="70" />
<ColumnDefinition MinWidth="70" MaxWidth="70" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>

WPF Window resize "eats" controls width

I have an issue im struggling a day now. Im trying to center some controls into a Grid layout. I have 2 columns and i want half of the controls centered ad the 1st column and other half to the second column
When the window resize some of them get "eaten" on the edges , and i wasent able to identify the issue
Can anyone spot the issue?
<Grid Margin="0,2,0,-2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
//.......
<ComboBox x:Name="optMenuLeft" Margin="0,271,0,0" VerticalAlignment="Top" Height="26" HorizontalAlignment="Center" Width="170" Grid.RowSpan="2" />
<Label Content="Menu" Margin="141,271,390,0" VerticalAlignment="Top" HorizontalContentAlignment="Right" HorizontalAlignment="Center" Width="69" Grid.RowSpan="2" />
<ComboBox x:Name="optBedOccupancyLeft" VerticalAlignment="Top" Height="26" Grid.RowSpan="2" HorizontalAlignment="Center" Width="170" Margin="0,240,0,0"/>
<Label Content="Bed Occupancy" Margin="0,240,270,0" VerticalAlignment="Top" HorizontalContentAlignment="Right" Grid.RowSpan="2" HorizontalAlignment="Center" Width="94"/>
//.......
<ComboBox Name="optMenuRight" Margin="255,271,175,0" Grid.Column="1" VerticalAlignment="Top" Height="26" HorizontalAlignment="Center" Width="170"/>
<Label Content="Menu" Margin="176,271,353,0" Grid.Column="1" VerticalAlignment="Top" HorizontalContentAlignment="Right" HorizontalAlignment="Center" Width="71"/>
<ComboBox Name="optBedOccupancyRight" Margin="255,240,175,0" Grid.Column="1" VerticalAlignment="Top" Height="26" HorizontalAlignment="Center" Width="170" Grid.RowSpan="2"/>
<Label Content="Bed Occupancy" Grid.Column="1" Margin="0,240,200,0" VerticalAlignment="Top" HorizontalContentAlignment="Right" Grid.RowSpan="2" HorizontalAlignment="Center" Width="94"/>
//.....
The simplest way is to use grids inside grid. The outer grid will split the window into two columns. The inner grids will split the columns into four cells (2x2). Just center the inner grids and it will work like a charm.
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid x:Name="LeftColumn" VerticalAlignment="Center" HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Label Content="Bed Occupancy" />
<ComboBox x:Name="optBedOccupancyLeft" Grid.Column="1" />
<Label Content="Menu" Grid.Row="1"/>
<ComboBox x:Name="optMenuLeft" Grid.Column="1" Grid.Row="1" />
</Grid>
<Grid x:Name="RightColumn" VerticalAlignment="Center" HorizontalAlignment="Center>
<!-- the same as left column -->
</Grid>
</Grid>
Btw, notice, that when you want split some are to equal columns (or rows or both), you can use UniformGrid:
<UniformGrid x:Name="LayoutRoot" Rows="1">
<Grid x:Name="LeftColumn" />
<Grid x:Name="RightColumn" />
</UniformGrid>
There is also more advanced approach that I often use:
Use UniformGrid to define columns. The xaml is smaller and cleaner.
Use HeaderedContentControl to define labels and inputs
Use Grid's SharedSizeScope feature, to make width of label equal: https://msdn.microsoft.com/en-us/library/system.windows.controls.grid.issharedsizescope%28v=vs.110%29.aspx
<UniformGrid x:Name="LayoutRoot" Rows="1">
<StackPanel x:Name="LeftColumn" Grid.IsSharedSizeScope="True"
HorizontalAlignment="Center" VerticalAlignment="Center">
<HeaderedContentControl Header="Bed Occupancy" Style="{StaticResource LabelValueContentControl}">
<ComboBox x:Name="optBedOccupancyLeft" />
</HeaderedContentControl>
<HeaderedContentControl Header="Menu" Style="{StaticResource LabelValueContentControl}" >
<ComboBox x:Name="optMenuLeft" />
</HeaderedContentControl>
</StackPanel>
<StackPanel x:Name="RightColumn" Grid.IsSharedSizeScope="True">
<!-- the same as left column -->
</StackPanel>
</UniformGrid>
The LabelCalueControlStyle is take advantage of shared column size
<Style x:Key="LabelValueContentControl" TargetType="HeaderedContentControl">
<Setter Property="Padding" Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="HeaderedContentControl">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="LabelValueContentControl.Label" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentPresenter ContentSource="Header"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Right" />
<ContentPresenter Grid.Column="1" Margin="{TemplateBinding Padding}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

WPF button arrangement

I am new to WPF, and I am trying to arrange a bunch of buttons:
I have 5 Marllet buttons: up, down, left, right, reset.
Arrange up, down, left and right at top, bottom, left and right respectively
And I want the reset button to take the center position surrounded by other 4 buttons.
Here is my current WPF code, but it lines up the reset button next to other 4, and the other 4 just lined up from top to bottom
<StackPanel Orientation="Horizontal">
<StackPanel>
<Button Content="Reset" Width="75" Height="30" Click="btnResetCrop3D_Click"/>
</StackPanel>
<StackPanel>
<Button FontFamily="Marlett" FontSize="20" Content="3" Width="20" Height="30"/>
<Button FontFamily="Marlett" FontSize="20" Content="4" Width="20" Height="30"/>
<Button FontFamily="Marlett" FontSize="20" Content="5" Width="20" Height="30"/>
<Button FontFamily="Marlett" FontSize="20" Content="6" Width="20" Height="30"/>
</StackPanel>
</StackPanel>
I am sorry I don't have enough credits to post an image. So if you have any confusion regarding my description, please let me know.
As #JeffRSon said use Grid
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="1" Grid.Column="0" Content="Left" />
<Button Grid.Row="0" Grid.Column="1" Content="Top" />
<Button Grid.Row="1" Grid.Column="2" Content="Right" />
<Button Grid.Row="2" Grid.Column="1" Content="Bottom" />
<Button Grid.Row="1" Grid.Column="1" Content="Center" />
</Grid>
Same thing done with a DockPanel
<DockPanel Height="300" Width="300">
<Button Content="Top" DockPanel.Dock="Top" Height="100" Width="100"/>
<Button Content="Bottom" DockPanel.Dock="Bottom" Height="100" Width="100"/>
<Button Content="Left" Height="100" Width="100"/>
<Button Content="Right" DockPanel.Dock="Right" Height="100" Width="100"/>
<Button Content="Last Child" Height="100" Width="100"/>
</DockPanel>
Personal choice, though :)

Cant select Items in Listbox when using Tabcontrol WPF

I have a problem with the selection of items in a Listbox, when the Listbox is in a Tabcontrol.
I can't select any item in the Listbox.
I am filling the Listbox dynamically via code-behind, also I am using drag and drop on it, though, Drag and drop is working with the tabcontrol.
Here is my XAML code:
<Window x:Class="SPInstallApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:toolkit="clr-namespace:Microsoft.Windows.Controls;assembly=WPFToolkit.Extended"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="SharePoint 2010 - wspSync" Height="450" Width="700" AllowDrop="True" Icon="/SPInstallApp;component/Images/favicon.ico">
<Window.Resources>
<DataTemplate x:Key="CustomListBoxTemplate">
<StackPanel>
<Grid Margin="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48 "/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image Source="{Binding Path=ImageSource}" Grid.Column="0" Grid.RowSpan="3" Margin="0,0,5,0" />
<TextBlock
Padding="0,5,0,0"
Text="{Binding Path=Title}"
Grid.Column="1"
Grid.Row="0"
FontWeight="Bold"/>
<TextBlock
Padding="0,0,0,5"
Text="{Binding Path=Description}"
Grid.Column="1"
Grid.Row="1"
FontStyle="Italic" />
<TextBlock
Padding="0,0,0,5"
Text="{Binding Path=Status}"
Grid.Column="1"
Grid.Row="2"
FontStyle="Italic" Foreground="#FFDE2B2B" />
</Grid>
</StackPanel>
</DataTemplate>
</Window.Resources>
<toolkit:BusyIndicator IsBusy="True" BusyContent="Bitte warten..." Name="busyIndicator">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Label Content="Websitecollection wählen:" Grid.Row="0" Grid.Column="0" Margin="5,0,0,0" />
<ComboBox Grid.Row="1" Grid.Column="0" Height="20" Margin="10,0,10,10" Name="cbWebsitecollection" SelectionChanged="CbWebsitecollectionSelectionChanged" />
<TabControl Grid.Row="2" Grid.Column="0" Name="tc" SelectionChanged="TcSelectionChanged" Margin="10,0,10,0">
<TabItem Header="Installieren">
<ListBox AllowDrop="True" Background="#CCC" Drop="ListBoxDrop" Name="lbDropbox" IsSynchronizedWithCurrentItem="True" ItemTemplate="{StaticResource CustomListBoxTemplate}" KeyUp="LbDropboxKeyUp" />
</TabItem>
<TabItem Header="Websitecollection">
<CheckBox Content="test" />
</TabItem>
</TabControl>
<Label Grid.Row="2" Grid.Column="0" VerticalAlignment="Center" HorizontalAlignment="Center" FontWeight="Bold" Content="drag 'n' drop" Margin="10" Drop="ListBoxDrop" Name="lbDescription" />
<Button Grid.Row="3" Grid.Column="0" Name="cmdSync" Content="Synchronisieren" Margin="10" Width="100" HorizontalAlignment="Right" Click="CmdSyncClick" />
<Image Grid.Row="3" HorizontalAlignment="Left" Name="Logo" Source="/SPInstallApp;component/Images/logo.gif" Margin="10" MouseUp="LogoMouseUp" MouseEnter="LogoMouseEnter" MouseLeave="LogoMouseLeave" />
</Grid>
</toolkit:BusyIndicator></Window>
If i remove the Tabcontrol, everything is working.
I hope someone can help me or know what the problem is.
greets
I have found the problem.
The problem is how Microsoft designed the MessageHandles.
If a child of an item throws a message (for example selectionChanged) and the message is not handles, the message goes to the parent Item.
So, in my case, if I click on an item in the ListBox, the (unhandled) message "selectionChanged" was sent to the TabControl, this was the problem. Because i have custom code in the TabControl.selectionChanged it always ran my code, instead of selecting the item in the ListBox.
The workaround is, to put this code in the selectionChanged eventhandler of the ListBox:
private void ListBox_selectionChanged(object sender, DragEventArgs e)
{
e.handled = true;
}
This avoids the transfer of the message from the child messagehandler to the parent messagehandler.
I hope u can undersand my explanation.

DockPanel Resizing and TextBox linebreak

I have a DockPanel with two Grids (DockPanel.Dock="Right/Left"). In the left i have a TreeView and in the right i have some TextBoxes. If i resize my window the panels resize proportinal.
My problem is, if i write long text in a TextBox the TextBox enlarge and hide my left DockPanel instead of a break the text.
I have set minwidth of the left DockPanel to '300' and set TextWrapping in the TextBoxes to 'wrap' but nothing helps.
Source:
<Grid Background="#FF58ACFC" Name="main">
<DockPanel>
<Grid DockPanel.Dock="Right" Margin="0,0,5,0">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="200" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="26"/>
<RowDefinition Height="26"/>
<RowDefinition Height="26"/>
<RowDefinition Height="60" />
<RowDefinition Height="26"/>
<RowDefinition />
</Grid.RowDefinitions>
<Label Content="Titel:" Grid.Row="0"/>
<TextBox Grid.Row="1" IsReadOnly="False">
<Label Content="Frage:" Grid.Row="2"/>
<TextBox Grid.Row="3" TextWrapping="Wrap" IsReadOnly="False" AcceptsReturn="True">
<Label Content="Antwort:" Grid.Row="4"/>
<TextBox Grid.Row="5" IsReadOnly="False" TextWrapping="Wrap" />
</Grid>
<Grid DockPanel.Dock="Left" Margin="5,0,0,0">
<DockPanel>
<Grid DockPanel.Dock="Left">
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Top" Height="26">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="Kategorie" Grid.Column="0"/>
<Button Grid.Column="1" BorderThickness="0" HorizontalAlignment="Right">
</Grid>
<TreeView HorizontalAlignment="Stretch" VerticalAlignment="Stretch"Padding="0,0,15,0" />
</DockPanel>
</Grid>
<Grid DockPanel.Dock="Right">
<DockPanel LastChildFill="True">
<Grid DockPanel.Dock="Top" Height="26">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="Lernkarten" Grid.Column="0"/>
<Button Grid.Column="1" Width="26" Click="ButtonAddItem_Click">
</Grid>
<ListView />
</DockPanel>
</Grid>
</DockPanel>
</Grid>
</DockPanel>
</Grid>
That's pretty much why Dockpanels are useless :-)
I suggest using Grid..

Categories