WrapPanel with 2 items WPF - wpf

I want to show a big text next to an image, in a resizable window.
I found here that it's pssible to use a WrapPanel, but this control need a fixed width and the width of my window is not fixe.
I tried the following code, but sometimes, the text is placed under the image (depanding on the window size) :
<Border Grid.Row="0" BorderBrush="Black" BorderThickness="1" CornerRadius="1" Background="PaleGoldenrod" Grid.Column="0" Margin="5">
<StackPanel Orientation="Vertical" Opacity="0.8" >
<WrapPanel Orientation="Horizontal" Width="{Binding ElementName=RadGridViewFoldersSettingsRSP, Path=Width}">
<Image Source="/Pics/Resources/btn_about_active.png" Margin="2" Width="20"/>
<TextBlock Text="blablabla" TextWrapping="WrapWithOverflow" Margin="2" FontStyle="Italic"/>
</WrapPanel>
</StackPanel>
</Border>
This border is above a grid as wide as the window.
Can you help me ?

To resolve my issue, i'm going to another way :
<Border Grid.Row="0" BorderBrush="Black" BorderThickness="1" CornerRadius="1" Background="PaleGoldenrod" Grid.Column="0" Margin="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="/Pics/Resources/btn_about_active.png" Margin="2" Width="20" Grid.Column="0"/>
<TextBlock Grid.Column="1" Text="BIG TEXT" TextWrapping="WrapWithOverflow" Margin="2" FontStyle="Italic"/>
</Grid>
</Border>
Thanks to mm8 for his reactivity !

Related

How can I turn on both vertical and horizontal borders for the itemTemplate Control?

I created the item template control and set its border thickness and color in Data Template. This is my ItemTemplate code:
<ItemsControl x:Name="VimshottariDasha" Margin="-10,83,-124,-267" FontSize="16" Grid.ColumnSpan="3" BorderThickness="0">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderThickness="1" BorderBrush="DimGray">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Col1" />
<ColumnDefinition SharedSizeGroup="Col2" />
<ColumnDefinition SharedSizeGroup="Col3" />
</Grid.ColumnDefinitions>
<Button Background="Transparent" BorderThickness="0" x:Name="DashaButton" Grid.Column="0" Content="{Binding rulerName}" Command="{Binding SelectedDasha}" CommandParameter="{Binding Content, RelativeSource={RelativeSource Self}}"/>
<TextBlock Grid.Column="1" Text="{Binding rulerStartDate, StringFormat=dd-MMM-yyyy HH:mm:ss}" />
<TextBlock Grid.Column="2" Text="{Binding rulerEndDate, StringFormat=dd-MMM-yyyy HH:mm:ss}"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
How do I show both vertical and horizontal borders regardless of stack orientation?
The same thing happens in another itemTemplate but in reverse, whose stack orientation is set to Horizontal. I can see vertical borders in the second item Control but no Horizontal borders.
This is the current Output, it has horizontal Borders inside but no vertical ones(Stack orientation is vertical by default)
This is second ItemControl with horizontal stack orientation it is missing horizontal borders.
Thanks.
First go through this link to understand how to add border around TextBlock.
You can also use Label instead of TextBlock to add border.
Now look into modified code:
ItemsControl Grid.Row="0" x:Name="VimshottariDasha" Margin="10" FontSize="16" Grid.ColumnSpan="3" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<!--<Border BorderThickness="1" BorderBrush="DimGray">-->
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="Col1" />
<ColumnDefinition SharedSizeGroup="Col2" />
<ColumnDefinition SharedSizeGroup="Col3" />
</Grid.ColumnDefinitions>
<Button Background="Transparent" BorderThickness="1" x:Name="DashaButton" Grid.Column="0" Content="{Binding rulerName}" />
<Border Grid.Column="1" BorderThickness="1" BorderBrush="Blue">
<TextBlock Text="{Binding rulerStartDate, StringFormat=dd-MMM-yyyy HH:mm:ss}" />
</Border>
<Label BorderThickness="1" BorderBrush="Bisque" Grid.Column="2" Content="{Binding rulerEndDate, StringFormat=dd-MMM-yyyy HH:mm:ss}"/>
</Grid>
<!--</Border>-->
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
A WPF Border control only draws the border along its outer edges. [It is possible to turn of one or more edges by setting its BorderThickness.]
If you want to create border lines between individual controls, you either have to use multiple Border elements, or manually draw the internal lines yourself.
For example
<Border HorizontalAlignment="Center" VerticalAlignment="Center" BorderBrush="Green" BorderThickness="2" >
<Grid Height="24" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Column 1" VerticalAlignment="Center" />
<TextBlock Grid.Column="2" Text="Column 2" VerticalAlignment="Center" />
<TextBlock Grid.Column="4" Text="Column 3" VerticalAlignment="Center" />
<Path Stroke="Red" StrokeThickness="1" Data="M 0,0 M 2,2 M 1,0 L 1,2" Stretch="Fill" Grid.Column="1" />
<Path Stroke="Red" StrokeThickness="1" Data="M 0,0 M 2,2 M 1,0 L 1,2" Stretch="Fill" Grid.Column="3" />
</Grid>
</Border>

Make textbox width automatically changable in Stackpanel which is in Border, WPF

I wanted to put Button in TextBox, but as I found it's not possible so I decided to do something like this:
Xaml for this looks as shown below:
<Border Grid.Row="4" Grid.Column="2" Margin="10,0,10,0"
BorderBrush="Gray" BorderThickness="1">
<StackPanel Orientation="Horizontal" Margin="0,0,0,0">
<TextBox BorderBrush="LightGray" BorderThickness="1" Text="{Binding WaybillNumber}"
Width="245"/>
<Button Content="*" Width="15" BorderThickness="1"/>
</StackPanel>
</Border>
The problem I have is that, when I resize my window (decreasing width) my Button dissapears:
I want it to behave as DateTimePicker does. I have tried many ways to make TextBox width auto adjustable ( * in width isn't correct input, auto decreases width of TextBox, I also tried to define style resource in StackPanel resources for TextBox width, but it doesn't work too), but Haven't found correct way yet.
Replace the StackPanel with a Grid:
<Border Margin="10,0,10,0" BorderBrush="Gray" BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBox BorderBrush="LightGray" BorderThickness="1" Text="{Binding WaybillNumber}" />
<Button Grid.Column="1" Content="*" Width="15" BorderThickness="1"/>
</Grid>
</Border>
use Grid instead of StackPanel. Setting fixed size (Width/Height) is not a good idea for adaptive layout. Grid will allow TextBox to stretch.
one option is to have separate columns for TextBox and Button:
<Border Grid.Row="4" Grid.Column="2" Margin="10,0,10,0"
BorderBrush="Gray" BorderThickness="1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox BorderBrush="LightGray" BorderThickness="1" Text="{Binding WaybillNumber}" />
<Button Content="*" Grid.Column="1" Width="15" BorderThickness="1"/>
</Grid>
</Border>
alternatively place them in the same cell and let Button overlap TextBox (it will look like as a part of TextBox but can hide part of a long text):
<Border Grid.Row="4" Grid.Column="2" Margin="10,0,10,0"
BorderBrush="Gray" BorderThickness="1">
<Grid>
<TextBox BorderBrush="LightGray" BorderThickness="1" Text="{Binding WaybillNumber}" />
<Button Content="*" HorizontalAlignment="Right" Margin="2" Width="15" BorderThickness="1"/>
</Grid>
</Border>

Xaml C# How to add corner radius each side of two columns, with Gridsplitter

(I'm french...sorry ;-) )
<Grid x:Name="grid2" Margin="0,5,0,5">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="3" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border x:Name="b3" BorderBrush="DarkOrange" CornerRadius="8,0,0,8" BorderThickness="1,1,1,1" Background="DarkOrange">
<TextBlock Grid.Column="0" TextAlignment="Center" Background="Transparent" >Partie Gauche</TextBlock>
</Border>
<GridSplitter Grid.Column="1" Background="Red" HorizontalAlignment="Stretch" ShowsPreview="True" ResizeDirection="Columns" />
<Border x:Name="b4" BorderBrush="DarkGreen" CornerRadius="0,8,8,0" BorderThickness="1,1,1,1" Background="DarkGreen">
<TextBlock Grid.Column="2" TextAlignment="Center" Background="Darkgreen" >Partie Droite</TextBlock>
</Border>
</Grid>
with CornerRadius Grid.Column="0" and Grid.Column="2"
without CornerRadius Grid.Column="2"
I do not put corners on the Grid.Column="2", keeping the layout.
Thanks!

How to get the value of the margin of a border?

I'm a beginner in WPF and have to add functionality to someone's user interface. Here's part of the code.
<Border BorderBrush="Black" BorderThickness="1" Grid.Row="1" >
<Grid Grid.Row="0">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="{Binding ElementName=passFailIndicator, Path=Width}"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Background="Black" local:StretchPanel.Proportion="1" Name="imageBorder" Grid.Column="0">
<Border BorderThickness="1" Margin="2" BorderBrush="Green" HorizontalAlignment="Left" VerticalAlignment="Top" Width="{Binding ElementName=imageBorder, Path=Width}">
<Grid Width="{Binding ElementName=imageBorder, Path=Width}">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="{Binding ElementName=imageSelectExpander, Path=Width}"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" x:Name="image" Source="{Binding DisplayImage, Mode=OneWay}" VerticalAlignment="Top" Stretch="Uniform" HorizontalAlignment="Left" StretchDirection="Both" MouseMove="image_MouseMove" />
<TextBlock Name="pxPos" Text="mouse position" HorizontalAlignment="Right" VerticalAlignment="Bottom" MaxHeight="20" Foreground="Aqua"></TextBlock>
<Expander Grid.Column="1" VerticalAlignment="Top" Name="imageSelectExpander">
<ComboBox x:Name="imageSelect" ItemsSource="{Binding AvailableImages, Mode=OneWay}" SelectedIndex="{Binding ImageSelect, Mode=TwoWay}" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Margin="4" Padding="4" MaxHeight="40"></ComboBox>
</Expander>
</Grid>
</Border>
</Border>
<Border x:Name="passFailIndicator" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="100" Height="100">
<Viewbox Stretch="Uniform" >
<Path Style="{Binding TestResult, Mode=OneWay, Converter={StaticResource testResultToPathStyle}}" Margin="2" />
</Viewbox>
</Border>
</Grid>
</Border>
I'm trying to access the Margin="2" on line 10. When I use this.imageBorder.Margin, I get {0,0,0,0}. How would I get the 2 (of course, this value may change)?
thanks
edit:
FrameworkElement fe = (FrameworkElement)this.imageBorder.Child;
pxPos.Text = (string.Format("x:{0} y:{1}", (int)((double)(pt.X - fe.Margin.Left) * (double)this.image.Source.Width / this.image.ActualWidth), (int)((double)(pt.Y - fe.Margin.Top)*(double)this.image.Source.Height / this.image.ActualHeight)));
The Border labeled imageBorder does not have its Margin property set to anything, so you are getting the default Margin, which is 0.
To get the Margin property of the Border inside your named border, either give it an x:Name so you can access it in code behind, or look in imageBorder.Child property to find the child Border object, then cast it to a FrameworkElement to get its Margin property.
As for why you're getting {0,0,0,0}, the Margin property is of type Thickness, which consists of properties for Left, Top, Right, and Bottom. If you set a margin to a single value, such as 2, it automatically converts that to a Thickness object with all 4 of its properties set to 2.

How to make a StackPanel Width that of another StackPanel?

I have two dockpanels which each have a left StackPanel.
The width of the bottom StackPanel is determined by the width of the text is in it.
The width of the top StackPanel should be the same as the width of the bottom StackPanel.
I've tried to bind the Width of the top StackPanel to the Width of the bottom StackPanel via ElementName but this doesn't work.
How can I make the top width the same as the bottom width?
<StackPanel>
<DockPanel LastChildFill="True" Height="100" >
<StackPanel Width="{Binding ElementName=LeftMenuText, Path=Width}"
DockPanel.Dock="Left"
Background="Yellow">
<TextBlock
Text="This is some text."/>
</StackPanel>
<StackPanel DockPanel.Dock="Right"
Background="Orange">
</StackPanel>
</DockPanel>
<DockPanel
Height="3"
Background="Black"></DockPanel>
<DockPanel LastChildFill="True" Height="100">
<StackPanel Name="LeftMenuWrapper"
DockPanel.Dock="Left"
Background="Yellow">
<TextBlock
Text="This is some text that is longer."/>
</StackPanel>
<StackPanel DockPanel.Dock="Right"
Background="Blue">
</StackPanel>
</DockPanel>
</StackPanel>
Bind it to ActualWidth of LeftMenuWrapper:
<StackPanel>
<DockPanel LastChildFill="True" Height="100" >
<StackPanel Width="{Binding ElementName=LeftMenuWrapper, Path=ActualWidth}"
DockPanel.Dock="Left"
Background="Yellow">
<TextBlock
Text="This is some text."/>
</StackPanel>
<StackPanel DockPanel.Dock="Right"
Background="Orange">
</StackPanel>
</DockPanel>
<DockPanel
Height="3"
Background="Black"></DockPanel>
<DockPanel LastChildFill="True" Height="100">
<StackPanel Name="LeftMenuWrapper"
DockPanel.Dock="Left"
Background="Yellow">
<TextBlock
Text="This is some text that is longer."/>
</StackPanel>
<StackPanel DockPanel.Dock="Right"
Background="Blue">
</StackPanel>
</DockPanel>
</StackPanel>
Just to add to your arsenal another way to do this. You can also use Grid's IsSharedScope property:
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel Grid.IsSharedSizeScope="True">
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="TextHolder"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="Yellow">
<TextBlock Text="This is some text."/>
</Border>
<Border Grid.Column="1" Background="Orange"/>
</Grid>
<Border Height="3" Background="Black"/>
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="TextHolder"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Border Background="Yellow">
<TextBlock Text="This is some text that is longer."/>
</Border>
<Border Grid.Column="1" Background="Blue"/>
</Grid>
</StackPanel>
</Page>
You can do this using Grids with a SharedSizeGroup instead of DockPanels. I.e.
<StackPanel Grid.IsSharedSizeScope="True">
<Grid Height="100" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="A"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Width="{Binding ElementName=LeftMenuText, Path=Width}"
DockPanel.Dock="Left"
Background="Yellow">
<TextBlock
Text="This is some text."/>
</StackPanel>
<StackPanel Grid.Column="1" DockPanel.Dock="Right"
Background="Orange">
</StackPanel>
</Grid>
<DockPanel
Height="3"
Background="Black"></DockPanel>
<Grid Height="100">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="A"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Name="LeftMenuWrapper"
DockPanel.Dock="Left"
Background="Yellow">
<TextBlock
Text="This is some text that is longer."/>
</StackPanel>
<StackPanel Grid.Column="1" DockPanel.Dock="Right"
Background="Blue">
</StackPanel>
</Grid>
</StackPanel>
The key things to remember are to give each column inside your grids a SharedSizeGroup with the same name ("A" in this example), and add Grid.IsSharedSizeScope="True" to a shared parent of the Grids (the StackPanel containing the Grids in this example)

Resources