Draw a circle in WPF using min(width, height)/2 as radius - wpf

How I can draw a circle in WPF (without code-behind) using min(width, height)/2 as radius?

you can do it in pure XAML you just need to use Binding for the values. You also have to make sure that everything is named
<Grid Name="grdMain">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75" Name="Col1" />
<ColumnDefinition Width="100" Name="Col2" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="75" Name="Row1" />
<RowDefinition Height="100" Name="Row2" />
</Grid.RowDefinitions>
<Ellipse Grid.Column="1" Grid.Row="1"
Canvas.Top="50"
Canvas.Left="50"
Fill="#FFFFFF00"
Height="{Binding RowDefinitions/ActualHeight, ElementName=Row1, Mode=OneWay}"
Width="{Binding ColumnDefinitions/ActualWidth, ElementName=Col1, Mode=OneWay}"
StrokeThickness="5"
Stroke="#FF0000FF"/>
</Grid>

Where does width and height come from? Example XAML for a circle is:
<Canvas Background="LightGray">
<Ellipse
Canvas.Top="50"
Canvas.Left="50"
Fill="#FFFFFF00"
Height="75"
Width="75"
StrokeThickness="5"
Stroke="#FF0000FF"/>
</Canvas>
A circle is just an Ellipse where Height = Width.

Related

Sharing columns or rows in a grid

I'm trying to create an asymmetrical layout using a Grid where i have 2 rows, 2 columns and an extra shared column as follows:
<Grid Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="200" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle
Grid.Row="0"
Grid.Column="0"
Width="200"
Height="200"
Fill="Red" />
<Rectangle
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Width="250"
Height="200"
Fill="Blue" />
<Rectangle
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Width="250"
Height="200"
Fill="Yellow" />
<Rectangle
Grid.Row="1"
Grid.Column="2"
Width="200"
Height="200"
Fill="Green" />
</Grid>
But however i try to set it up, the second column always collapses unless i explicitly set a fixed width (in this case 50px). Why is this happening?
Shouldn't the second column resize itself to the remainder of each rectangle?
Using a Converter i managed to manually calculate the shared column size by placing the content of the first column in a container and binding the width of the shared column to the ActualWidth of that container subtracted by the first column width.
e.g.
<Grid Background="Black">
<Grid.RowDefinitions>
<RowDefinition Height="200" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="200" />
<ColumnDefinition Width="{Binding ElementName=Rect3, Path=ActualWidth, Converter={StaticResource SharedColumnConverter}, ConverterParameter=200}" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle
Grid.Row="0"
Grid.Column="0"
Width="200"
Height="200"
Fill="Red" />
<Rectangle
Grid.Row="0"
Grid.Column="1"
Grid.ColumnSpan="2"
Width="250"
Height="200"
Fill="Blue" />
<Rectangle
Name="Rect3"
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Width="250"
Height="200"
Fill="Yellow" />
<Rectangle
Grid.Row="1"
Grid.Column="2"
Width="200"
Height="200"
Fill="Green" />
</Grid>

How to cut TextBox width to prevent out of the Grid?

I have the next layout
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.RowSpan="2" Grid.Column="0" Width="60" Height="60" />
<StackPanel Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Orientation="Horizontal">
<TextBlock Text="Title should be long" HorizontalAlignment="Left" />
<Ellipse Fill="White" Stroke="White" Width="7" Height="7" />
</StackPanel>
<TextBlock Grid.Row="1" Grid.Column="1" Text="Message" />
<TextBlock Grid.Row="1" Grid.Column="2" Text="Info" />
</Grid>
I have an issue in the StackPanel which hosts a Title and Ellipse, the goal is the Online marker by the ellipse whitch should be placed at the end off the title. But it shouldn't out of a view part.
I have tried to put TextBox and Ellipse into cells of the Grid unfortunatly it doesn't help.
<Grid Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2">
<Grid.ColumnsDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnsDefinitions>
<TextBlock Grid.Column="0" Text="Title should be long" HorizontalAlignment="Left" />
<Ellipse Grid.Column="1" Fill="White" Stroke="White" Width="7" Height="7" />
</Grid>
In my mind it should render correct, but the ellipse is out of view port again.
This is a Expression Blend layout scrinshots, the same layout is rendering in runtime.
The Grid bounds:
The TextBox bounds:
The Ellipse bounds:
So the TextBox and Ellipse is out of the grid :(
Update: I need the next behaviour of layout
1) Short title, the ellipse attached to the title end
2) Long title, the ellipse attached to the right side of container
I tried your code and it renders fine (in other terms it renders in the viewport. See red arrow). Please find attached a screenshot of the results. (I added the showgridlines just to illustrates the rows and cols)
//--- Changed testing and fixed code for intended effect ---//
Code changes in XAML: Swapped the width values for the columndefinitions. Added Textwrapping to textblock in order to see entire text. (You could opt for texttrimming instead depending on your aesthetics.)
<Grid Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Title should be really really really really really long" HorizontalAlignment="Left" TextWrapping="Wrap" />
<Ellipse Grid.Column="1" Fill="White" Stroke="White" Width="7" Height="7"/>
</Grid>
Outcome:

How to organize elements inside a Button

i'm new to wpf .
i got a wpf button ,
in it i need to place 2 elements a textblock and a viewbox encapsulating a canvas
the problem is i can't seem to see the canvas at all , unless i give it static values for its size
<Button Margin="10,30,10,10" Padding="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Me" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"></TextBlock>
<Viewbox Margin="0,0,0,5">
<Canvas Background="red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Grid.Column="1" >
<Ellipse HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="4" ></Ellipse>
</Canvas>
</Viewbox>
</Grid>
</Button>
iv'e also attempted this using a stack panel with an horizontal orintation
in any case the canvas does not show
any thoughts of what i'm doing wrong ?
thanks.
Attached Grid properties only work when at the Grid-child-level, i.e. the properties set on the canvas do not take effect they should be set on the container, the ViewBox which is a direct child of the Grid.
Viewboxes only work if the content has a concrete size, you probably need neither the ViewBox nor the Canvas. If you want the Ellipse to be a circle set Stretch="Uniform"
The contents of Buttons do not stretch by default you should set HorizontalContentAligment and its vertical counterpart to Stretch.
e.g.
<Button Margin="10,30,10,10" Padding="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Me" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"></TextBlock>
<Ellipse Stretch="Uniform" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Stroke="Black" StrokeThickness="4"></Ellipse>
</Grid>
</Button>

Control as background of Grid

I have a grid, and I need to have a control as background of this grid. This control will be a progressbar, but it's my problem how to create it.
I can't find how can I set a control as background of grid.
Have you got any experience with this kind of problem?
<DataTemplate x:Key="TodoItemWeeklyTemplate">
<Grid MinWidth="800" Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Source="{Binding Occurrence.Appointment.Icon, Converter={StaticResource imgConverter}}" Width="16" Height="16" Stretch="Fill" />
<TextBlock Grid.Column="1" HorizontalAlignment="Left" MaxWidth="130" Text="{Binding Occurrence.Appointment.Subject}" />
</Grid>
</DataTemplate>
Here is how I would do it:-
<Grid MinWidth="800">
<Rectangle x:Name="Background" Fill="Green" Width="{Binding PercentDone, Converter={StaticConverter WidthConv}, ConverterParameter=800}" HorizontalAlignment="Left" />
<Grid Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Source="{Binding Occurrence.Appointment.Icon, Converter={StaticResource imgConverter}}" Width="16" Height="16" Stretch="Fill" />
<TextBlock Grid.Column="1" HorizontalAlignment="Left" MaxWidth="130" Text="{Binding Occurrence.Appointment.Subject}" />
</Grid>
</Grid>
Where WidthConv is an instance of a class added to the usercontrol resources that implements IValueConverter. The Convert method would take the input percentage value and apply it to the parameter to return the width the rectangle needs to be to represents that percentage value.
The important point here is that Grid naturaly overlays elements on each other when the occupy the same area.
You cannot set a control as a background as it is of Brush Type.
But if you want to emulate that you can put your Grid in another one like that :
<Grid>
<Grid>
<!-- put your Content here -->
</Grid>
<ProgressBar />
</Grid>

Fill panel with rectangles

I want to fill a panel with rectangles, and when the panel is resized, the rectangles should resize as well.
Why doesn't the following work?
<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<StackPanel HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Rectangle Fill="Red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Rectangle Fill="Green" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Rectangle Fill="Blue" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
</StackPanel>
</Page>
I would prefer not to use a Grid because of the pain of adding/removing columns and rearranging the children. (I was looking forward to StackPanel because if I wanted to add a yellow Rectangle at the beginning, I just declare it. I don't have to re-order the others by hand.)
Or a UniformGrid:
<UniformGrid Columns="1">
<Rectangle Fill="Red"/>
<Rectangle Fill="Green"/>
<Rectangle Fill="Blue"/>
</UniformGrid>
You're using a StackPanel whose behavior is to take the size of its children. Use a Grid which takes the whole available size:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Fill="Red" Grid.Row="0" />
<Rectangle Fill="Green" Grid.Row="1" />
<Rectangle Fill="Blue" Grid.Row="2" />
</Grid>

Resources