How to Fill SolidColorBrush/Ellipse [duplicate] - c#

I am trying to create this in WPF (I realize I could just use an image, but I am trying to learn WPF):
(source)
This is what I have so far but it isn't producing the desired result, in that, the textbox seems completely hide the ellipse whereas it should simply have a transparent background:
<StackPanel>
<TextBlock HorizontalAlignment="Left" Margin="144,207,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top"/>
<Ellipse HorizontalAlignment="Left" Height="52" Margin="142,189,0,0" Stroke="Black" VerticalAlignment="Top" Width="52"/>
</StackPanel>

You can put things like this in a viewbox to make scaling easier, something like this. You'll need to remove the stack panel, it's going to stack items one on top of the other which isn't what you're after here. I used a grid in this case.
<Viewbox Width="100" Height="100">
<Grid Width="20" Height="20">
<Ellipse Stroke="Black"/>
<TextBlock HorizontalAlignment="Center" Text="i" TextAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Viewbox>

Or you can use the unicode character: ⓘ
code 0x24D8
<TextBlock Text="ⓘ" FontSize="52" />

So a stackpanel will place the first item at the top, the second just below it, third below the second, and so forth. What you could do is use a Canvas or a Grid. Like the stackpanel, they are "Content Controls" and support placing multiple objects inside of them like you have done with the stackpanel.
So a really quick way to do what you're trying to accomplish would be:
<Grid >
<Ellipse HorizontalAlignment="Left" Height="52" Stroke="Black" VerticalAlignment="Top" Width="52"/>
<TextBlock Text="i" FontSize="52" Margin="18,-13,-6,13" />
</Grid>

You can do it using a border and a TextBlock. A square border will become a circle if you make its CornerRadius equals half its Width (or Height):
<Border Width="100" Height="100" CornerRadius="50" BorderBrush="Black" BorderThickness="2">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"
FontSize="50" Foreground="Blue" >i</TextBlock>
</Border>

Don't use a StackPanel for this, the purpose of it is to stack things, not show them overlapped, you're using the wrong tool for that. Use a Grid, it's far more suited for what you're trying to do.
To have a transparent background, you have to either set the TextBlock's Background property to Transparent, or set a null background.
Background={x:Null}

Related

Adding border to entire grid when I'm trying to add it to only a TextBlockC#

I'm trying to add a border to only a TextBlock but instead it is creating it around the entire grid. Here is the code :
<Border BorderBrush="Black" BorderThickness="6">
<TextBlock x:Name="txtInputUsername" HorizontalAlignment="Left" Margin="65,54,0,0" TextWrapping="Wrap" Text="Username" VerticalAlignment="Top" TextAlignment="Center" FontFamily="Open Sans" FontSize="20" Background="#FFF3F3F3" OpacityMask="Black"/>
</Border>
This is happening because child elements of a Grid will assume the Height and Width of the Grid (or the Grid cell) they are placed in, unless otherwise specified. The Border just looks like it is wrapping around the grid, because it is using it to infer its size.
There are a few ways to fix this, with the easiest being to specify the HorizontalAlignment and VerticalAlignment of the Border to Center. This causes the Border to snap around the bounds of the TextBlock instead of inferring its size.
In your case, it still produces some odd results because of your use of Margin to position the label. The Margin is still counted as being part of the control, so anything the wraps around the control will have to be larger to accommodate it. You should avoid that if at all possible, but if you really want to do it that way, more the Margin to the Border.
<Grid>
<Border
Margin="65,54,0,0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
BorderBrush="Black"
BorderThickness="6">
<TextBlock
x:Name="txtInputUsername"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Background="#FFF3F3F3"
FontFamily="Open Sans"
FontSize="20"
OpacityMask="Black"
Text="Username"
TextAlignment="Center"
TextWrapping="Wrap" />
</Border>
</Grid>
A better way to handle this though, is to learn about the different layout containers, and how to use them to position your controls, instead of Margin. These can be nested within each other to create almost any layout you can imagine, in a fairly nice, clean way.

WPF How to make a Viewbox aware of its available space from within a StackPanel

I have a custom WPF control based on Soroosh Davaee’s ImageButton example at http://www.codeproject.com/Tips/773386/WPF-ImageButton. The custom control combines an Image and TextBlock in a horizontal StackPanel within a Button. (BTW, to get Soroosh’s example to run, I had to edit the solution properties so that “SampleView” is the startup project rather than “ExtendedButton” being the startup project.)
I want the text in the TextBlock to automatically shrink if necessary to avoid clipping at the right edge if the text is too long to fit naturally in the button. For example, if I edit Soroosh's MainWindow.xaml to make the button text too long to fit...
...
<EB:ImageButton Width="100" Height="30" Content="TextTooLongToFitInTheButton" Grid.Row="2"
...
<EB:ImageButton Width="100" Height="30" Content="TextTooLongToFitInTheButton" Grid.Row="2"
...
...the result is the following buttons with clipped text:
In researching this, it seems the simplest way to auto-shrink the content of a TextBlock is to wrap it within a Viewbox:
<Viewbox StretchDirection="DownOnly" Stretch="Fill">
<TextBlock ... />
</Viewbox>
DownOnly apparently prevents the Viewbox from enlarging the text to fill the space, and Fill (as opposed to Uniform) seems to tell it to stretch (shrink) only the dimension that needs to shrink (i.e. the horizontal dimension in my case).
In Soroosh's example Generic.xaml file, I wrapped the TextBlock in such a Viewbox:
<Button >
<StackPanel Orientation="Horizontal">
<Image Margin="2 0"
Source="{TemplateBinding Image}"
Width="{TemplateBinding ImageWidth}"
Height="{TemplateBinding ImageHeight}"
Visibility="{TemplateBinding Image,Converter={StaticResource VisibilityConvertor}}"
VerticalAlignment="Center"/>
I added--> <Viewbox StretchDirection="DownOnly" Stretch="Fill">
<TextBlock Text="{TemplateBinding Content}"
VerticalAlignment="Center"/>
I added--> </Viewbox>
</StackPanel>
</Button>
This produced exactly the same clipped button text. Just experimenting, I tried forcing the Viewbox to have a fixed width...
<Viewbox StretchDirection="DownOnly" Stretch="Fill" Width="60">
...which produced this:
...which shows the capability of the Viewbox, if only it could somehow know its available width when it's inside the StackPanel.
I did note that if I wrap the Viewbox around the whole StackPanel, it successfully auto-shrinks the entire content of the StackPanel:
<Button >
<Viewbox StretchDirection="DownOnly" Stretch="Fill" Width="60">
<StackPanel Orientation="Horizontal">
<Image Margin="2 0"
Source="{TemplateBinding Image}"
Width="{TemplateBinding ImageWidth}"
Height="{TemplateBinding ImageHeight}"
Visibility="{TemplateBinding Image,Converter={StaticResource VisibilityConvertor}}"
VerticalAlignment="Center"/>
<TextBlock Text="{TemplateBinding Content}"
VerticalAlignment="Center"/>
</StackPanel>
</Viewbox>
</Button>
...which produces very nearly what I want:
...but both the image and text are shrunk, and I want only the text shrunk.
How can I make the Viewbox, wrapping only the TextBox, know its available width (and height, I suppose) from within a cell of the StackPanel?
This is a common problem. The solution is simply to not use a StackPanel to do any kind of layout that requires re-sizing of child controls. It's simply not the correct Panel for the job. Instead, try using a Grid panel, which will resize its child controls. The StackPanel control is really only good for the most basic of layout duties... try anything more adventurous and you'll find yourself getting these issues.
One other alternative is to use the TextBlock.TextTrimming Property to trim the text instead... you could put the full text into a ToolTip too.

Cannot scroll to bottom wpf

I have a listbox with objects but I cannot scroll to the bottom of the page. What is the problem? This is the code that I'm using.
<Grid>
<Image Name="Nietcomment" Source="write.png" Width="70" Margin="350,-850,0,0" Tap="Login_popup" Visibility="Visible"/>
<Image Name="welcomment" Source="write2.png" Width="70" Margin="350,-850,0,0" Tap="Login_popup_remove" Visibility="Collapsed"/>
<ScrollViewer Name="scrollview" VerticalScrollBarVisibility="Visible" Margin="0,0,0,0" Foreground="Black">
<StackPanel>
<TextBlock x:Name="NTitelComment" Text="{Binding}" TextWrapping="Wrap" FontSize="25" Margin="10,0,10,0" Foreground="#FFE5001b"/>
<Line Stretch="Fill" Stroke="Black" X1="0" X2="1" Y1="0" Y2="0" Margin="10,0,10,0"/>
<TextBlock x:Name="tijdComment" Text="{Binding}" Margin="50,0,10,0" Foreground="Black"/>
<Image Height="20" Width="20" Margin="-380,-20,0,0" Source="/PostDateIcon.png"/>
<ListBox Margin="0,0,0,20" Name="lbComments" VerticalAlignment="Top" />
</StackPanel>
</ScrollViewer>
</Grid>
If you put a border around your ScrollViewer, can you see if it goes outside of the screen maybe? Will it help to set a fixed height of the Grid or ScrollViewer?
Keep in mind the phone has built in scroll, so your ScrollViewer maybe doesn't play well with it.
With so much fixed margins, your layout will be impossible to manage, especially when dealing with differents screen resolutions and especially with negative margins.
Anyway, right now, you have two scrollviewers, as your listbox contains one as well.
You should disable the listbox scrollviewer or it will prevent your page to scroll.
Just change your listbox:
<ListBox
Margin="0,0,0,20"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
Name="lbComments"
VerticalAlignment="Top" />
It will disable it's scrollviewer and allow it to scroll with the rest of the page.

How to set Separator`s color to invisible in WPF?

This how it looks now:
<Separator Height="10" Margin="0" Width="168"
HorizontalAlignment="Center" VerticalAlignment="Top"
Background="SteelBlue"/>
The problem, that I don't know what color Background will be needed? Is there any way out? Or need to know what color I need?
"Invisible" Brush in WPF is called Transparent, you can set Background="Transparent" to set the Separator to invisble.
Or you can set the Visibiliy="Hidden" to preserve the space of the control without showing it.
You can use transparent
<Separator Height="10" Margin="0" Width="168"
HorizontalAlignment="Center" VerticalAlignment="Top"
Background="Transparent"/>

How to place a slider over on top of a videobrush

I am attempting to create a slider control which will determine the scaletransform of a videobrush in my MainPage, and was wondering if it was possible to somehow place this slider on top of the videobrush (which I would like to be full screen)? Currently I am using a grid for my layout where a videobrush takes up the whole screen except for two buttons on the bottom of the screen, but I would like to possibly use a canvas and place this slider in a way that would account for the current and future screen sizes of a Windows Phone device. I am unsure of how to exactly accomplish this without setting constant dimensions for the slider. For instance the slider may be placed horizontally near the bottom of the screen in Portrait mode and would have a 50 pixel space between the left and right sides. Could someone assist with how this could be done?
EDIT
Placing a single child element over the videobrush works, although I would like to place more than one slider which gives an error. I also wanted to add information above and below each slider so I chose a stackpanel to do this (yet only one stackpanel as a child element is allowed?).
<Border x:Name="videoRectangle" Grid.Row="0" Grid.ColumnSpan="2" >
<Border.Background>
<VideoBrush x:Name="viewfinderBrush">
<VideoBrush.RelativeTransform>
<CompositeTransform x:Name="viewfinderBrushTransform" CenterX=".5" CenterY=".5" Rotation="90" />
</VideoBrush.RelativeTransform>
</VideoBrush>
</Border.Background>
<!--<StackPanel VerticalAlignment="Top">
<TextBlock x:Name="resolutionValueTextBlock" HorizontalAlignment="Center" Text="{Binding Value, ElementName=resolutionSlider}"/>
<Slider x:Name="resolutionSlider" HorizontalAlignment="Stretch" Margin="50,5,50,5"/>
<TextBlock x:Name="resolutionTextBlock" HorizontalAlignment="Center" Text="resolution"/>
</StackPanel>-->
<StackPanel VerticalAlignment="Bottom">
<TextBlock x:Name="zoomNumberTextBlock" HorizontalAlignment="Center" Text="{Binding Value, ElementName=zoomSlider}"/>
<Slider x:Name="zoomSlider" HorizontalAlignment="Stretch" Margin="50,5,50,5"/>
<TextBlock x:Name="zoomTextBlock" HorizontalAlignment="Center" Text="zoom"/>
</StackPanel>
</Border>
If possible I would like both stackpanels to be available, but if not I guess I would have to use the bottom one only.
Stay with the Grid:
<Grid>
<Rectangle>
<Rectangle.Fill>
<VideoBrush ... />
</Rectangle.Fill>
</Rectangle>
<Slider HorizontalAlignment="Stretch"
VerticalAlignment="Bottom"
Margin="50,5,50,5"/>
</Grid>

Categories