How to center BusyIndicator to the center of MainWindow? - wpf

I created sample Wpf application and installed Extended WPF Toolkit (NuGet package). Here's my xaml code for showing BusyIndicator.
<Window x:Class="WpfApp3.Progress"
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:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
xmlns:local="clr-namespace:WpfApp3"
mc:Ignorable="d"
WindowStyle="None"
BorderThickness="0"
Title=""
VerticalAlignment="Center"
HorizontalAlignment="Center"
SizeToContent="WidthAndHeight"
d:DesignWidth="300"
d:DesignHeight="300">
<xctk:BusyIndicator IsBusy="True"
HorizontalAlignment="Center"
VerticalAlignment="Center"></xctk:BusyIndicator>
</Window>
Showing the progress window is triggered with this code:
private void Button_Click(object sender, RoutedEventArgs e)
{
Progress w = new Progress
{
Owner = Application.Current.MainWindow,
WindowStartupLocation = WindowStartupLocation.CenterOwner
};
w.Show();
}
My question is simple. How to show BusyIndicator in the middle of the MainWindow screen. As Shown from the picture below it's not centered as it should be. Note that I use SizeToContent="WidthAndHeight"

Having a seperate window to display the busy indicator and will result in unwanted behaviour. What happens if the original window is maximised, moved etc.?
Consider adding the busy indicator to the main screen. Usually I create an overlay region that is used to display message dialogs, progress bars etc..
<Window>
<Grid>
<Application stuff ....>
</Application stuff>
<ContentControl regions:RegionManager.RegionName="OverlayRegion"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
</Window>
I'm using Prism here but you can replace the ContentControl with anything, such as the BusyIndicator and manipulate the visibility of the control.

Solved it by removing Window.SizeToContent property and by adding VerticalAlignment and HorizontalAlignment properties to BusyIndicator (actually now I used spinner, but this doesn't make any difference in solution).
<Window x:Class="Test.Progress"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
WindowStyle="None"
AllowsTransparency="True"
BorderThickness="0"
Title=""
WindowStartupLocation="CenterOwner"
ShowInTaskbar="False"
Background="Transparent"
d:DesignWidth="200"
d:DesignHeight="200"
MaxWidth="250"
MaxHeight="250">
<xctk:BusyIndicator IsBusy="True"
HorizontalAlignment="Center"
VerticalAlignment="Center"></xctk:BusyIndicator>
</Window>
The problem is because BusyIndicator was not designed to use it in separate window
The BusyIndicator is a ContentControl. What this means is that the BusyIndicator can contain a single child element within it?s open and closing tags.
Additionally if you do, first thing that is shown is small ui control (12x12 pixels) and after some latency finally the progress bar/busy indicator is shown.
By specifying SizeToContent='WidthAndHeight', xaml automatically resizes height and width relative to content. In this case (12x12) ui control is taken, and after some latency time finally as mentioned above busy indicator is shown. But by that time, the xaml ui renderer already applied SizeToContent and therefore you would have to manually re-position the progress bar.
I'm not really sure how xaml ui renderes works without specifying SizeToContent, but apparently it re-positions the busy indicator correctly after it is shown.

Related

Making PART of a WPF window click-through, but not its controls

In order to achieve a dropshadow effect, my window is slighty bigger than its main content with a transparent "border" around it. I am curious if there's a possibility to make this invisible border (coloured part in image) click-through only and prevent main content from being click-through.
This thread explains what to do in order to make the whole window click-through:
Making a WPF window click-through, but not its controls
Is there any way to adapt this approach for what I intend do achieve?
Only a window with a fully transparent background is really click through. For a semi-transparent window you could for example minimize the window yourself when clicking on the shadow, e.g.:
private void Grid_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.OriginalSource == outer)
WindowState = WindowState.Minimized;
}
XAML:
<Window x:Class="WpfApp1.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"
mc:Ignorable="d"
Title="MainWindow" Height="300" Width="300"
AllowsTransparency="True" WindowStyle="None">
<Window.Background>
<SolidColorBrush Color="Red" Opacity="0.3" />
</Window.Background>
<Grid x:Name="outer" Background="Transparent" MouseLeftButtonDown="Grid_MouseLeftButtonDown">
<Grid Background="Silver" Margin="10">
<TextBlock>GUI</TextBlock>
</Grid>
</Grid>
</Window>

Using a properties grid with a tree control

I want to create a tree control that when the user clicks on an element in the tree control, a properties grid is populated with its properties.
I've created a tree control as a user control and I'm using Jaime Oliveras' property grid. I have both on a WPF window but I can't seem to figure out how to make the two communicate with each other.
The XAML on the Main window is:
<Window 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:advanced="clr-namespace:OptionsStrategyTree.ViewModel"
xmlns:local="clr-namespace:OptionsStrategyTree.ViewModel"
xmlns:Controls="clr-namespace:System.Windows.Controls"
x:Class="OptionsStrategyTree.MainWindow"
mc:Ignorable="d"
Title="MainWindow" Height="400" Width="500">
<Grid>
<local:UserStrategyTree HorizontalAlignment="Left" Margin="18,6,0,13"
Width="195" Height="340" />
<Controls:WpfPropertyGrid x:Name="StrategyTreePropertyGrid"
HorizontalAlignment="Left" Height="340" Margin="233,6,0,0"
VerticalAlignment="Top" Width="239"/>
</Grid>
</Window>
I've had this properties grid working nicely when the controls are all on the same XAML window. But when I've created a tree control as a user control, it's a separate entity in its own XAML space that seems to be isolated from everything else. Is there any way to connect the two?

RadBusyIndicator always selected when designer is clicked

I have a RadBusyIndicator on my UserControl like so:
<Grid>
<!-- Other Content -->
<t:RadBusyIndicator IsBusy="{Binding IsBusy}"></t:RadBusyIndicator>
</Grid>
And whenever I click in the design view it goes to the BusyIndicator.
I can set the Panel.ZIndex to be negative to select the "Other Content", but this will cause the RadBusyIndicator to be behind the "Other Content"
I tried using a binding for the ZIndex like so:
<t:RadBusyIndicator Panel.ZIndex="{Binding BusyZIndex}" IsBusy="{Binding IsBusy}"></t:RadBusyIndicator>
But it doesn't help.
So the question is:
How do I have the RadBusyIndicator on "Top" of all the "Other Content" but still be able to click(in the designer) and go to the xaml line for that control?
The BusyIndicator needs to be "on top" to be in front of the controls. That makes it also on top in the designer.
There may be better ways of solving this, but what comes into mind is to make the BusyPanel a Resource on the UserControl, and then add it in the Grid control OnApplyTemplate or Loaded by code.
Here is the UserControl's XAML.
<UserControl x:Class="WpfApplication2.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:t="REFERENCE.TO.THE.RAD.ASSEMBLY"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<t:RadBusyIndicator x:Key="TheBusyIndicator" IsBusy="{Binding IsBusy}">
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<Button Content="Some content to the button"
Height="25"
Width="200"/>
</Grid>
</UserControl>
I have added the BusyIndicator as a Resource with the Key "TheBusyIndicator".
I have also added x:Name="LayoutRoot" to the Grid which will contain the BusyIndicator.
The Grid can of course have another name if it in fact is not the layout root control.
By adding the BusyIndicator to the Children collection last, it will appear in front of all other controls that are added by the markup code.
Here is the code
UserControl's Constructor:
public UserControl1()
{
this.Loaded += new RoutedEventHandler(UserControl1_Loaded);
}
The execting code:
private void UserControl1_Loaded(object sender, RoutedEventArgs e)
{
this.LayoutRoot.Children.Add(this.Resources["TheBusyIndicator"] as RadBusyIndicator);
}
I never use UserControls anymore, only CustomControls where the XAML goes to "Generic.xaml" and I have no editor to work in. So I have not seen this problem for a while.

WPF window not minimizing/maximizing

I am a novice WPF programmer. My problem is as below.
I have a WPF application and on the home screen, when I click on the maximize button, it does not maximize the screen, instead repositions it to the top left column. If I increase/decrease the screen size through click and drag, the maximize button works just fine. The window properties are set up as follows:
<Window x:Class="MyApp.Home"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
x:Uid="Window_Main"
x:Name="HomeWindow"
WindowStyle="None"
AllowsTransparency="True"
WindowStartupLocation="CenterScreen"
Margin="0"
BorderBrush="Transparent"
BorderThickness="0"
Title="Home"
MinWidth="1000" MinHeight="800"
ResizeMode="CanResizeWithGrip"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
SizeToContent="WidthAndHeight"
Visibility="Visible"
d:DesignHeight="1080" d:DesignWidth="1200">
The XAML for button is:
<Button x:Uid="btnRestore" x:Name="btnRestore" Height="20" Width="20" Style="{DynamicResource Control_WindowControlBoxStyle}" Margin="5,0,0,0" ToolTip="Toggle Restore" Click="btnRestore_Click" />
And the code for btnRestore_Click is simple:
private void btnRestore_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Maximized;
}
I am sure there must be some silly mistake that I am committing but not able to figure out what that is. Seems simple but caught me in spin. Any help would be appreciated.
You have SizeToContent="WidthAndHeight", which will make the window resize to whatever size the content in the Window is.
Either remove this property, or make sure first child of your Window tag doesn't have a size set

Window that is supposed to be fullscreen in WPF touchscreen application is moving when inner listbox is scrolled

I am writing a GUI application to run on a touchscreen device using VB.NET and WPF--it must be full screen at all times, like a kiosk app; the window must not be able to resize or move in any way. The window contains a ListBox that users can currently scroll through by dragging across the list. The problem I'm seeing is that when the user drags across the list, the whole window moves a bit, exposing the desktop underneath, then springs back into place once the user stops dragging. I have not been able to figure out how to keep the window stationary while still allowing users to drag across the ListBox to view all list items. Here is a somewhat simplified version of my code:
<Window
x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
WindowStyle="None"
WindowState="Maximized"
WindowStartupLocation="CenterScreen"
KeyboardNavigation.TabNavigation="None"
Topmost="True"
Focusable="False"
ResizeMode="NoResize"
ShowInTaskbar="False"
MaxHeight="1080px"
MaxWidth="1920px">
<Grid>
<ListBox
x:Name="docList"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
BorderThickness="0">
<TextBlock Text="Item1" />
<TextBlock Text="Item2" />
<TextBlock Text="Item3" />
<TextBlock Text="Item4" />
<TextBlock Text="Item5" />
<TextBlock Text="Item6" />
</ListBox>
</Grid>
</Window>
I believe that if you handle the OnManipulationBoundaryFeedback(object sender, TouchEventArgs e) event on the listbox, and set the e.Handled property true, that should prevent the "bounce" of the application window.
It may also be possible (I hadn't thought of it until just now) to handle the event at the Window level, since it is a bubbling event, to mitigate the chance of any other controls causing the same behaviour.

Resources