Position the Popup control in the screen and Textblock text center - c#

I'm quite new in C# WPF. I want my Popup control to be positioned in a certain coordinates of the user's screen. and I want to make my textblock text center in the textblock itself. I tried to add a block but it doesn't work. Look at my XAML codes: (I'm 97% done in my personal project. :) )
Also, look at my screenshot, I put a red box there, I want my popup control to be there, although it is not my priority cause the original position is quite fine with me, but I would be glad if this will be moved.
Next, look at the annoying text, it is not centered.
The current position of the popup is in the left most and upper most part of my screen.
<Window x:Class="KeyLocks_Notifier.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>
<Popup Name="Popup1" AllowsTransparency="True" PlacementRectangle="0,0,30,50" Placement="Center"
PopupAnimation="Fade">
<Border BorderBrush="{x:Null}" Height="50">
<TextBlock Name="myPopupText"
Background="#FF9700FF"
Height = "40"
Width="180"
Foreground="White" FontWeight="Bold" FontSize="16" HorizontalAlignment="Center" VerticalAlignment="Center">
<TextBlock.Effect>
<DropShadowEffect/>
</TextBlock.Effect>
</TextBlock>
</Border>
</Popup>
</Grid>
</Window>

On the window :
In XAML there is a WindowStartupLocation on the root level with 3 options (Manual, CenterScreen, CenterOwner)
If you want a custom Location on your screen you need to set WindowStartupLocation to Manual and set the Top & Left with pixel
For your popup :
You can set the Placement to custom
Example Here
And for your text position Here

Related

How to Draw Content in Non-Client Area Properly with Regular Caption Buttons

I am trying to make a window with the default caption buttons and title bar, and still be able to place arbitrary content within the window chrome; however, all the solutions I have tried leave an approximately 5 unit margin to the right of the caption buttons. Here is a basic example:
<Window x:Class="SemiCustomWindowChrome.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SemiCustomWindowChrome"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525" Name="Window">
<WindowChrome.WindowChrome>
<WindowChrome UseAeroCaptionButtons="True" ResizeBorderThickness="5" GlassFrameThickness="1,28,1,1"/>
</WindowChrome.WindowChrome>
<Window.Template>
<ControlTemplate>
<AdornerDecorator>
<ContentPresenter Content="{Binding ElementName=Window, Path=Content}"/>
</AdornerDecorator>
</ControlTemplate>
</Window.Template>
<Grid>
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<Button Content="Click me daddy!" WindowChrome.IsHitTestVisibleInChrome="True" Height="28"/>
<TextBlock Text="Custom Window Test" Margin="6.5"/>
</StackPanel>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="White" FontFamily="MS Calibri" FontWeight="ExtraLight" Text="Hello There"/>
</Grid>
The above code produces this.
To be clear, I would like to remove the white padding to the right of the caption buttons in the window chrome so that the window is exactly the same as any other, with the only difference that I can put controls in the non-client area (the window chrome).
All help is appreciated!
If there is a more stable way to do it with DWM that does not include the use of a WindowChrome element I would appreciate if someone could give me an example.
WindowChrome.WindowChrome>
<WindowChrome GlassFrameThickness="0.5,28,0,0.5" NonClientFrameEdges="Right"/>
</WindowChrome.WindowChrome>
<Window.Template>
<ControlTemplate>
<ContentPresenter Content="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=Window}, Path=Content}"/>
</ControlTemplate>
</Window.Template>
This took a very long time to find. Originally I thought that the WindowChrome class was just completely broken, and it is to an extent, but I managed to use it anyways. The other solutions I came up with were a lot more complicated, and eventually, it just seemed a lot easier to just try and mess around with WindowChrome. I will work on a modified version of the class specifically for Windows 10, but until then, this works. I hope this helps somebody.
To use this code, just put it in at the top of the content area in the XAML for a window.

Keeping controls in the visible area

I've got a grid with several TextBoxes in it. I want to keep this grid fixed at the bottom of my main window. So if the user scrolls down the grid should basically stay in it's place.
One way I thought of doing this was to get some sort of value from the ScrollViewer and add it to the grids Canvas.TopProperty. However I am not sure which value changes when the user scrolls up or down.
Then don't put the scroll on the main window. Put ScrollViewer only on the content (rows) that you want to scroll. Careful not to use an auto for the height of the rows with the ScrollViewer or the container will grow to support all the content and the Scroll does not come into play.
One way:
<Window x:Class="Sample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
<ListBox>
<!--Hardcoded listbox items just to force the scrollbar for demonstration purposes -->
<ListBoxItem>Item1</ListBoxItem>
<ListBoxItem>Item2</ListBoxItem>
<ListBoxItem>Item3</ListBoxItem>
<ListBoxItem>Item4</ListBoxItem>
<ListBoxItem>Item5</ListBoxItem>
<ListBoxItem>Item6</ListBoxItem>
<ListBoxItem>Item7</ListBoxItem>
<ListBoxItem>Item8</ListBoxItem>
<ListBoxItem>Item9</ListBoxItem>
<ListBoxItem>Item10</ListBoxItem>
<ListBoxItem>Item11</ListBoxItem>
<ListBoxItem>Item12</ListBoxItem>
<ListBoxItem>Item14</ListBoxItem>
<ListBoxItem>Item15</ListBoxItem>
<ListBoxItem>Item16</ListBoxItem>
<ListBoxItem>Item17</ListBoxItem>
<ListBoxItem>Item18</ListBoxItem>
<ListBoxItem>Item19</ListBoxItem>
<ListBoxItem>Item20</ListBoxItem>
<ListBoxItem>Item21</ListBoxItem>
<ListBoxItem>Item22</ListBoxItem>
</ListBox>
<Grid Panel.ZIndex="5" VerticalAlignment="Bottom" Background="DarkGray">
<StackPanel>
<TextBox HorizontalAlignment="Left" VerticalAlignment="Center">Text box 1</TextBox>
<TextBox HorizontalAlignment="Left" VerticalAlignment="Center">Text box 2</TextBox>
<TextBox HorizontalAlignment="Left" VerticalAlignment="Center">Text box 3</TextBox>
</StackPanel>
</Grid>
</Grid>

Layout two controls on a line in a stretchable WPF window

Here's a fairly common UI pattern: Text box that contains a path to the left, and a Browse button to the right of it. If the window resizes, the button stays to the right, but the text box stretches to reveal more/less of the path. So in the good old days of anchors, the button would be anchored to the right and the text box would be anchored both left and right.
Trying to replicate this in WPF seems to be worryingly difficult.
If I create a new window, it comes with a Grid layout by default. I place my text box to the left and size it appropriately, then place the button to its right. HorizontalAlignment for the text box is Stretch and for the button it is Right.
In my mind, this works as described, but in real life the text box doesn't resize at all, but instead tries to center itself in the window, while the button acts as expected. What gives?
Here is my XAML:
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" d:DesignHeight="241" d:DesignWidth="414" SizeToContent="WidthAndHeight">
<Grid>
<TextBox Height="23" HorizontalAlignment="Stretch" Name="textBox1" VerticalAlignment="Top" Margin="12,11,101,0" />
<Button Content="Button" Height="23" HorizontalAlignment="Right" Margin="0,11,12,0" Name="button1" VerticalAlignment="Top" Width="75" />
</Grid>
</Window>
You would create another GridControl with two columns, one with a fixed width for Browse button and another one for the TextBox.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="75" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" />
<Button Grid.Column="1" />
</Grid>
You can use a DockPanel and set LastChildFill property to true to ensure that the textbox uses all the available space:
<DockPanel LastChildFill="true">
<Button DockPanel.Dock="Right">Browse</Button>
<TextBox>Content</TextBox>
</DockPanel>

How do I make a WPF popup draggable using a thumb?

I've searched long and hard to find an example of this on the net. I've seen the alternative methods for this but I want to specifically use a thumb. In trying to hash out a solution I've been unable to get the functionality right/working as I'm fairly new to WPF. I'd be grateful if someone could give an example of how you may implement the above.
Cheers
A Popup doesn't give you an obvious way to move it; you can only place it relative to its placement target. However it does give you and additional offset relative to the placement target and that's enough to move it anywhere.
Here's a working markup-only solution that demonstrates a draggable Popup using a Thumb using Markup Programming. There is a text box that has a popup that pops up when the text box receives the keyboard focus. The popup has some text and a thumb.
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:p="http://markupprogramming.codeplex.com/markup/programming"
Height="300" Width="300">
<Grid>
<StackPanel>
<TextBox x:Name="textBox1" Width="200" Height="20"/>
</StackPanel>
<Popup Name="popup" PlacementTarget="{Binding ElementName=textBox1}"
IsOpen="{Binding IsKeyboardFocused, ElementName=textBox1, Mode=OneWay}">
<StackPanel Orientation="Horizontal">
<TextBlock Background="White" Text="Sample Popup content."/>
<Thumb Name="thumb" Width="20" Height="20"/>
</StackPanel>
<p:Attached.Operations>
<p:ScriptHandler Path="#FindElement('thumb').DragDelta">
#AssociatedObject.HorizontalOffset += #EventArgs.HorizontalChange;
#AssociatedObject.VerticalOffset += #EventArgs.VerticalChange;
</p:ScriptHandler>
</p:Attached.Operations>
</Popup>
</Grid>
</Window>

C# WPF - ScrollViewer + TextBlock troubles

I have a TextBlock within a ScrollViewer that aligns with stretch to its window. I need the TextBlock to behave as the following:
Resizes with window, no scrollbars
When resized below a certain width the TextBlock needs to keep a MinWidth and scrollbars should appear
TextWrapping or TextTrimming should work appropriately
How can I get this functionality?
I have tried several ways, involving bindings to ActualWidth & ActualHeight, but can't get it to work.
This can't be that difficult, what am I missing?
Here is a code sample to put in XamlPad (no MinWidth is set yet):
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<TextBlock TextWrapping="Wrap" Text="Some really long text that should probably wordwrap when you resize the window." />
</ScrollViewer>
</Window>
This works:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ScrollViewer HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
Name="Scroller">
<TextBlock HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
MinWidth="100"
Width="{Binding ElementName=Scroller, Path=ViewportWidth}"
TextWrapping="Wrap"
Text="Some really long text that should probably wordwrap when you resize the window." />
</ScrollViewer>
</Window>
Without more detail, the best I can do is provide the standard way of doing this. Basically, host your element (which has a minimum size) in a scroll viewer; when the scrollviewer is resized small enough such that the element cannot wholly fit inside it, it will automatically display scroll bars. Example:
<ScrollViewer>
<Button MinWidth="100" MinHeight="50"/>
</ScrollViewer>

Categories

Resources