Change control center in wpf - c#

I have some label "my text".
I have some UserControl, inside it have text ("text part") and some visual part near text.
Left picture is what i want to achieve. Right is what i got.
I want center my UserControl not by its default center but by custom point.
Because "my text" may vary in length, meanwhile it should be centered relative to my controls "text part" center.
Goal ^ Current ^

You will need to define separate columns, one which is centered for your centered texts, and another one for your visual label.
The tricky part now is synchronizing one column from within the UserControl with one outside of it. You can use SharedSizeGroups for this, like in this example, I just used a ContentControl instead of the UserControl for convenience:
<Grid IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid HorizontalAlignment="Stretch" Background="Red">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="colLeft"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="colRight"/>
</Grid.ColumnDefinitions>
<Label HorizontalAlignment="Center" Background="LightBlue">MyText</Label>
</Grid>
<ContentControl Grid.Row="1">
<Grid HorizontalAlignment="Stretch" Background="Yellow">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="colLeft"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="colRight"/>
</Grid.ColumnDefinitions>
<Label HorizontalAlignment="Center" Background="Lime">text part a little longer
</Label>
<Label Grid.Column="1">someVisualLabel</Label>
</Grid>
</ContentControl>

Related

How Can I Remove This Extra Grid Space?

How can I stop this Grid from expanding vertically and adding all this extra space between the rows?
<ContentPage.Content>
<StackLayout>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Source="testsquare" />
<Image Source="testsquare" Grid.Column="1"/>
<Image Source="testsquare" Grid.Row="1"/>
<Image Source="testsquare" Grid.Column="1" Grid.Row="1"/>
</Grid>
</StackLayout>
</ContentPage.Content>
This is what it should look like (ignore the background color change)
Use "Auto" instead of "*"
<RowDefinition Height="Auto"/>
It appears to be a bug, where the grid height is being treated as if the image is being displayed at its full height.
<Grid BackgroundColor="CornflowerBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Image Source="testsquare" />
<Image Source="testsquare" Grid.Column="1" />
</Grid>
There is a spacing property in Grid .
Grid has properties to control spacing between rows and columns. The following properties are available for customizing the Grid:
ColumnSpacing – the amount of space between columns. The default value of this property is 6.
RowSpacing – the amount of space between rows. The default value of this property is 6.
You can set RowSpacing or ColumnSpacing to check whether can solve it .
<StackLayout Padding="5">
<Grid RowSpacing="5" ColumnSpacing="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Source="icon.png" BackgroundColor="Accent"/>
<Image Source="icon.png"
BackgroundColor="Accent"
Grid.Column="1" />
<Image Source="icon.png"
BackgroundColor="Accent"
Grid.Row="1" />
<Image Source="icon.png"
BackgroundColor="Accent"
Grid.Column="1"
Grid.Row="1" />
</Grid>
</StackLayout>
About Image , The Aspect property determines how the image will be scaled to fit the display area, with Fill or AspectFill .(Default is AspectFit)

C# WPF always align controls relative to window background image

I have a WPF application where I use a background image.
<Window.Background>
<ImageBrush ImageSource="Images/background.png"/>
</Window.Background>
In the window I have grids and columns definitions.
<Grid ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
Everytime the window size is changed, the background image is resized, which is okay.
The problem is that the controls in the form are loosing their position.
The background looks this way:
I need to add textboxes in between the lines so it can look like this:
So far I tried canvas, dockpanel, putting the textboxes in different user control, but nothing helped.
The controls do not have margins/width or height only rowspan and columnspan.
Any idea would be helpful :) thanks!
Your Textboxes need to be sized relative to the window size. You can define the colum widths and line heights as fractions of the width and height by specifying a size with a star (*).
See example below for a starting point. You can of course tweak the numbers a bit.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*"/>
<ColumnDefinition Width="0.29*"/>
<ColumnDefinition Width="0.02*"/>
<ColumnDefinition Width="0.29*"/>
<ColumnDefinition Width="0.2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0.55*"/>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="0.1*"/>
<RowDefinition Height="0.1*"/>
</Grid.RowDefinitions>
<TextBox Grid.Row="1" Grid.Column="1"/>
<TextBox Grid.Row="1" Grid.Column="3"/>
<TextBox Grid.Row="3" Grid.Column="1"/>
<TextBox Grid.Row="3" Grid.Column="3"/>
</Grid>

WPF: Data Grid not horizontally scrollable

I have following DataGrid:
<Grid Margin="10" HorizontalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="Auto" MinHeight="80"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="150"/>
<ColumnDefinition MinWidth="300" Width="Auto"/>
<ColumnDefinition MaxWidth="30"/>
<ColumnDefinition MaxWidth="10"/>
<ColumnDefinition MaxWidth="30"/>
<ColumnDefinition MaxWidth="10"/>
<ColumnDefinition Width="*" MinWidth="400"/>
</Grid.ColumnDefinitions>
...
<ScrollViewer Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="7" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<DataGrid
ItemsSource="{Binding ExcelFileDataView, Mode=TwoWay}"
AutoGenerateColumns="True"/>
</ScrollViewer>
...
</Grid>
But when I make the app window smaller the whole window becomes horizontally scrollable instead of the DataGrid.
What do I need to do to make only the DataGrid horizontally scrollable?
Don't put the DataGrid into a ScrollViewer. It has scrollbars on its own, so move ...ScrollBarVisibility attributes to the DataGrid and everything will be fine.

ListView layouting

It looks simple, but it is unbelievable hard.
I want to have such layout:
It's ListView which should take a maximum height of buttons (number of visible buttons is dynamic).
I tried this
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
...
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel>
<Button/>
<Button/>
...
</StackPanel>
<ListView Grid.Column="1"/>
</Grid>
</Grid>
Problem: ListView has a very weird behavior to size self to content. If I add many items, then suddenly it takes all window space.
Question: how to limit ListView height to not exceed buttons total height (StackPanel height)?
P.S.: mvvm, so pure xaml is preferable.
P.S.S.: I have feeling it will be a binding of something to something. But of what to what?
You just need to data bind the ActualHeight of your StackPanel to the ListView.Height so that the ListView won't grow larger than the Button's StackPanel:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<StackPanel Name="ButtonPanel" Grid.Column="0">
<Button Content="Click" />
<Button Content="Click" />
<Button Content="Click" />
</StackPanel>
<ListView Grid.Column="1" ItemsSource="{Binding Tests}"
Height="{Binding ActualHeight, ElementName=ButtonPanel}" />
</Grid>
</Grid>
You can bind the MaxHeight property of your lower content grid to the ActualHeight of the buttons StackPanel. Futher more, you need to set the VerticalAlignment of the buttons panel to Bottom.
This way, you can add more parts in vertically, but still stick to the buttons panel height.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
...
<Grid Grid.Row="1"
MaxHeight="{Binding ElementName=ButtonPanel, Path=ActualHeight}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<StackPanel Name="ButtonPanel"
VerticalAlignment="Bottom">
<Button Content="Button"/>
<Button Content="Button"/>
<Button Content="Button"/>
</StackPanel>
<ListView Grid.Column="1"/>
<!-- Multiple controls can be added here,
but the lower part will still stick
to the size of the buttons panel -->
</Grid>
</Grid>

XAML Property elements

For a project I am using XAML. I have devided my screen in different parts. The moment when I add a button, I get an error.
The error:
'property elements cannot be in the middle of an element's content'
The code I am using for the button where the error has been found:
<Button x:Name="cntButton" Content="Connect" Grid.Column="1" Grid.Row="2" Click="cntButton_Click" />
Does anyone know what the problem is and how I have to solve it?
The rest of the code:
<Window x:Class="Pesten.View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Image Grid.RowSpan="4" Grid.ColumnSpan="3" Stretch="Fill" Source="pestenbg.jpg" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="5*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Button x:Name="cntButton" Content="Connect" Grid.Column="1" Grid.Row="2" Click="cntButton_Click" />
</Grid>
</Window>
You've defined an image in the grid before the grid properties. Move this to after the row and column definitions.
You're adding Button control in the wrong place of parent control:
Property elements cannot be in the middle of an element's content
Property elements cannot be in the middle of an element's content. They must be before or after the content. This error is occurs when you attempt to use property-element syntax within an element's content.
Move Image after ColumnDefinitions and before Button
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="4*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/>
<RowDefinition Height="5*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="2*"/>
</Grid.RowDefinitions>
<Image Grid.RowSpan="4" Grid.ColumnSpan="3" Stretch="Fill" Source="pestenbg.jpg" VerticalAlignment="Top" HorizontalAlignment="Center"/>
<Button x:Name="cntButton" Content="Connect" Grid.Column="1" Grid.Row="2" Click="cntButton_Click" />
</Grid>
or move both Image and Button above column/row definition but you cannot split it
Put the column and row definitions directly after the opening tag. All content should follow that (i.e. the and the ).

Categories