How to know when window control styling completed - c#

I have a window.xaml which has components with different kind of styling( border color red, opacity changed and so on). In one moment I want to create a screenshot and save to folder. But before that the window background should be transparent and someCanvas should be hidden.
How do I know when the styling method finished so I can take a screenshot?
public void SomeMethod()
{
ChangeWindowControlStyles();
//TODO: waint till 'ChangeWindowControlStyles' finished
TageScreenshotAndSave();
}
public void ChangeWindowControlStyles()
{
this.Background.Opacity = 0;
this.someCanvas.Visibility = Visibility.Collapsed;
//Some other stuff related to window content styling
}
public void TakeScreenshotAndSave()
{
//No multithreading happening here
//Just taking screenshot and saving to folder
}
EDIT
The window itself is transparent WindowStyle="None", that means it has no borders. In the start the window's Background.Opacity is set to 0.1 and all controls are visible (there are other controls than someCanvas that should always be visible).
Before screenshot is taken someCanvas is hidden and the Background.Opacity is set to 0.
Window.xaml
<Window
WindowStartupLocation="CenterScreen"
ResizeMode="NoResize"
WindowState="Maximized"
WindowStyle="None"
AllowsTransparency="True" >
<Window.Background>
<SolidColorBrush Opacity="0.1" Color="White"/>
</Window.Background>
<Grid Name="mainGrid" Background="Transparent" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0">
<!--Main canvas, function holder-->
<Canvas Name="canvasAlwaysVisible" Margin="0" Panel.ZIndex="5">
<!-- Controls that are always visible -->
</Canvas>
<Canvas x:Name="someCanvas" Margin="0" Background="Transparent" Visibility="Visibility">
<!-- Controls with styling -->
</Canvas>
</Grid>
</Window>
EDIT 2
Another thing to mention is that inside TakeScreenshotAndSave there is also System.IO operations like - get all folders in directory, creation new directory and so on. Maybe .NET sees that and it is ran asynchronously.

Looks like I found the solution. I don't know why it works, will need to investigate more. That TakeScreenshotAndSave method that I mentioned in code sample was somehow running on different thread. When wrap that method inside Application.Current.Dispatcher it worked!
public void SomeMethod()
{
ChangeWindowControlStyles();
var m_dispatcher = Application.Current.Dispatcher;
m_dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.ApplicationIdle,
new System.Threading.ThreadStart(delegate
{
TakeScreenshotAndSave(); //Now running on UI thread
}));
}

Related

Using WPF in an ElementHost control - pass data from the c# Control's constructor to the underlying XAML to allow for different instances

Running off a tutorial from CodeProject I've succeeded in adding a WPF item to my Winforms project. My WinformsProject adds a slightly altered version of ElementHost, which contains a xaml object as a child from a separate project (with the alterations to ElementHost seemingly just to pass property and methods between the two projects).
My XAML code is:
<UserControl x:Class="WindowsFormsControlLibrary1.RoundedButtonWithSVG"
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:windowsformscontrollibrary1="clr-namespace:WindowsFormsControlLibrary1"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="250">
<Grid>
<Button x:Name="myButton" HorizontalAlignment="Left" Background="White" Height="50" VerticalAlignment="Top" Width="250" BorderBrush="#FFBFBFBF" Click="myButton_Click">
<Button.Resources>
<Style TargetType="Border">
<Setter Property="CornerRadius" Value="5"/>
</Style>
</Button.Resources>
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Stretch="Uniform">
<Canvas Name="svg117" Width="32" Height="32" >
<!--Unknown tag: sodipodi:namedview-->
<Path xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Name="path115" Fill="#FF008A9F" StrokeThickness=".4025" Stroke="#FF008A9F">
<Path.Data> <!--Below is the SVG for an icon-->
<PathGeometry Figures="m31.63 0.27366c-0.12545-0.088189-0.29069-0.098564-0.4267-0.027534l-30.786 16.139c-0.19792 0.10375-0.27291 0.34517-0.16751 0.53991 0.048232 0.08899 0.12898 0.15682 0.22597 0.18955l9.4117 3.2015 0.17011 0.05507 2.6795 8.2814c0.04291 0.13288 0.1533 0.23384 0.2911 0.26696 0.03167 0.0072 0.06411 0.01117 0.09663 0.01117 0.10767 0 0.21091-0.0419 0.28704-0.11692l5.5775-5.4817 8.2128 2.7833c0.11327 0.03911 0.23872 0.02634 0.34144-0.03512 0.10272-0.06066 0.17295-0.16281 0.19203-0.27933l4.0599-25.14c0.02395-0.14964-0.04019-0.29968-0.16564-0.38747zm-30.003 16.381 26.809-14.053c0.0016-0.0012 0.0045-7.981e-4 0.0057 7.981e-4 0.0012 0.0016 8.12e-4 0.00439-8.12e-4 0.00559l-18.205 16.976-8.607-2.9218c-0.00231-7.98e-4 -0.00349-0.0032-0.00268-0.0056 2.842e-4 -7.98e-4 8.12e-4 -0.0016 0.00146-2e-3zm9.2038 3.4745 17.873-16.667c0.0016-0.0016 0.0041-0.0016 0.0057 0 2e-3 0.0012 2e-3 0.00399 4.06e-4 0.00559l-13.97 17.868c-0.0311 0.03871-0.05387 0.0834-0.06699 0.13129l-1.5805 5.6265c0 2e-3 -0.0018 4e-3 -0.0041 4e-3 -0.0022 0-0.0041-2e-3 -0.0041-4e-3zm3.077 7.0571 1.4303-5.0918 2.7969 0.94773-4.2223 4.1481c-0.0022 3.99e-4 -0.0043-7.98e-4 -0.0048-0.0032-4.1e-5 -3.99e-4 -8.1e-5 -3.99e-4 -8.1e-5 -7.98e-4zm13.097-1.9821-11.277-3.8221 14.987-19.168c8.12e-4 -2e-3 0.0028-0.00279 0.0049-2e-3 2e-3 7.981e-4 0.0028 0.00279 2e-3 0.00479l-3.712 22.984c-4.06e-4 2e-3 -0.0024 0.0036-0.0049 0.0032z" FillRule="NonZero"/>
</Path.Data>
</Path>
</Canvas>
</Viewbox>
</Button>
</Grid>
</UserControl>
Essentially the above is just a simple button, with rounded corners and an SVG image (which would all make our UI Girl exceedingly happy). Now I need a bunch of these, each with different text and images. My question is, can I somehow override the xaml settings based on fields from the c# constructor? So in this case, can I override the Figures property of the PathGeometry in the Xaml to set whatever image I need for the given button? Something like the following as the .xaml.cs file
public partial class ComboBoxWithGrid : UserControl
{
public ComboBoxWithGrid(string imageString)
{
this.boundImageStringProperty = imageString;
InitializeComponent();
}
public string boundImageStringProperty = ""; //Can I Inject this into the xaml in any way?
public Action buttonClickEvent;
private void button_Click(object sender, RoutedEventArgs e)
{
buttonClickEvent();
}
}
Doing the above would let me use the one xaml object for most of my buttons, just with different constructor arguments but I'm afraid I'm not XAML Literate enough to figure any of this out, and most guides I find online detail how to send data from the xaml constructor to the c# base (not the other way around). Is any of this possible?

Launch WPF Class Library Project Full Screen

I have a WPF class library (with a user control within it being my launch page (similar to MainWindow).
Code Snippet for User control is as follows:
<UserControl x:Class="ABC" ...... >
<Grid>
<Label>Hello World</Label>
</Grid>
</UserControl>
I created another WPF app (labelled Launcher) which would essentially call the this class library.
That project doesnt have any MainWindow (removed it) and am launching the User Control from App.xaml
<Application
x:Class="Launcher.App"
......
StartupUri="pack://application:,,,/Project;component/View/HelloWorld.xaml">
The app doesnt start in full screen ever and always need to maxime it on launching.
I know the answer should be in lines of removing the StartupUri from App.xaml and putting the App.xaml.cs
private void Application_Startup(object sender, StartupEventArgs e)
{
//What to put here
}
Since there is no MainWindow hence there is I cant do this:
MainWindow wnd = new MainWindow();
wnd.Title = "Something else";
//Set StartupMode = "Maximized"
wnd.Show();
Do you know the Size of your Screen , if so
WindowStyle="None"
WindowStartupLocation="Manual"
Top="0" Left="0"
ResizeMode="NoResize"
BorderThickness="0"
Height="1080" Width="1920"
If you need to figure it out in code behind
WindowStyle="None"
WindowStartupLocation="Manual"
Top="0" Left="0"
ResizeMode="NoResize"
BorderThickness="0"
Height="{Binding Height}" Width="{Binding Width}"
In order to get the size look here :
The First Answer

How to create an automatic animated carousel cyling images using C# or XAML?

I have done carousels in web development, but animating them in WPF through XAML or C# is new to me. There are examples on the web, but they either are outdated or not what I am looking for. Even when I play around with source code of other projects, it's not what I hope for.
I want to have images sliding left-to-right (horizontally) automatically. The user cannot interact with the images to stop the sliding. While I can do this manually in a ScrollViewer, the process is manual...
ScrollViewer doesn't have any dependencies for animation. I tried using this to see if it is possible, but the application would always crash. Example I used..
Another attempt I've tried is storing images in a StackPanel, making sure the StackPanel is the width of one of my images, then having DispatcherTimer set to animate the TranslateTransform's X property. But...that didn't go anywhere.
Using a ScrollViewer or StackPanel is not important at all. I just want to have a carousel-like effect automatically transitioning through images. Sort of like THIS
I'm currently using Visual Studio 2012 and 2013, if it helps.
Is there a way to do this?
I' ve prepared exemplary carousel in wpf. You might want to use the code in form of UserControl for instance. As you proposed I prepared carousel with use of StackPanel. Code of my form looks as follows:
<Window x:Class="WpfApplication2.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">
<Window.Resources>
<Storyboard x:Key="CarouselStoryboard">
<DoubleAnimation
Storyboard.TargetName="CarouselTransform"
Storyboard.TargetProperty="X"/>
</Storyboard>
</Window.Resources>
<Canvas>
<StackPanel Name="Carousel" Orientation="Horizontal">
<StackPanel.RenderTransform>
<TranslateTransform x:Name="CarouselTransform" />
</StackPanel.RenderTransform>
<Button Height="350" Width="525" Content="Page1"/>
<Button Height="350" Width="525" Content="Page2"/>
<Button Height="350" Width="525" Content="Page3"/>
</StackPanel>
<Button Click="Left_Click" Content="Left" HorizontalAlignment="Left" Margin="10,164,0,0" VerticalAlignment="Top" Width="45">
</Button>
<Button Click="Right_Click" Content="Right" HorizontalAlignment="Left" Margin="448,170,0,0" VerticalAlignment="Top" Width="45"/>
</Canvas>
</Window>
The Storyboard element within WindowResources defines animation to be performed. It will change X property of TranslationTransform applied to StackPanel "Carousel" - this will result in animated movement of that panel. 3 buttons within the panel simulates 3 panels of the carousel. At the bottom there are 2 buttons - one for moving left and second for moving right. There are callback methods bounded to them. Code behind of the form looks like that:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private int currentElement = 0;
private void Left_Click(object sender, RoutedEventArgs e)
{
if(currentElement < 2)
{
currentElement++;
AnimateCarousel();
}
}
private void Right_Click(object sender, RoutedEventArgs e)
{
if (currentElement > 0)
{
currentElement--;
AnimateCarousel();
}
}
private void AnimateCarousel()
{
Storyboard storyboard = (this.Resources["CarouselStoryboard"] as Storyboard);
DoubleAnimation animation = storyboard.Children.First() as DoubleAnimation;
animation.To = -this.Width * currentElement;
storyboard.Begin();
}
}
currentElement field holds information which panel is currently being displayed to the user. Method AnimateCarousel actualy starts the animation. It refers to Storyboard defined in Resources and sets its DoubleAnimation To property to the value to which Carousel panel should be moved. Then by calling Begin method on storyboard it performs animation.

How to update UI before (and after) long running UI process in WPF?

I apologize if this is a duplicate, but I have not been able to find a question with a similar situation. If this is a duplicate please provide a link.
I would like to show a "Loading..." overlay in my WPF application, when I am dynamically creating a lot of tabs. The overlay visibility is bound to a property called "ShowIsLoadingOverlay". However, the overlay is never shown.
Due to the fact that the tabs are visual elements I can't move the creation into a BackgroundWorker.
I have created a small prototype trying to explain the situation. This is the xaml:
<Window x:Class="WpfApplication5.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">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Label HorizontalAlignment="Center" VerticalAlignment="Center"
Visibility="{Binding ShowIsLoadingOverlay, Converter={StaticResource BooleanToVisibilityConverter}}"
Content="Loading..." />
<Button Grid.Row="1" Content="Load" Click="Button_Click" />
</Grid>
</Window>
And this is the code behind:
public partial class MainWindow : Window, INotifyPropertyChanged
{
private bool m_ShowIsLoadingOverlay;
public bool ShowIsLoadingOverlay
{
get
{
return m_ShowIsLoadingOverlay;
}
set
{
if ( m_ShowIsLoadingOverlay == value )
{
return;
}
m_ShowIsLoadingOverlay = value;
NotifyPropertyChanged( "ShowIsLoadingOverlay" );
}
}
public MainWindow()
{
InitializeComponent();
DataContext = this;
}
private void Button_Click( object sender, RoutedEventArgs e )
{
ShowIsLoadingOverlay = true;
CreateTabs();
ShowIsLoadingOverlay = false;
}
private void CreateTabs()
{
// Simulate long running process to create tabs
Thread.Sleep( 3000 );
}
// Implementation of INotifyPropertyChanged has been left out.
}
The problem is that the overlay is never shown. I know that it has something to do with the UI not updated correctly before and after the ShowIsLoadingOverlay property has changed. And I believe it also has something to do with the lack of using the dispatcher.
I have tried many, many combinations of Dispatcher.Invoke, Dispatcher.BeginInvoke surrounding when changing the property and/or surrounding the CreateTabs call. And I have tried changing the DispatcherPriority to "force" the overlay to show before starting to create the tabs. But I just can't make it work...
Could you please tell me how to accomplish this task? And more importantly; provide an explanation, because I do not get this.
In advance,
thank you.
Best regards,
Casper Korshøj
You cannot manipulate UI controls in a background thread. If you are using the main UI thread to create your TabItems, then you also cannot have a 'Busy' or 'Loading' indicator... this will only work if you are using a alternative thread for your long running process. This is because your 'Busy' indicator will only become updated once the long running process has completed if it runs on the same UI thread.

WPF borderless window with shadow VS2012 style

I'm trying to create an application that looks like Visual Studio 2012. I have used WindowChrome to remove the window borders, and changed the border color in my xaml.
What I don't know how to do is paint the shadow of the window, here you can see an screenshot of what I'm saying:
As you can see there is a shadow and its color is also the border color
Do you know how to implement it using WPF?
Update (October '17)
It has been four years now and I was interested in tackling this again and thus I have been messing around with MahApps.Metro once again and derived my own library based on it. My ModernChrome library provides a custom window that looks like Visual Studio 2017:
Since you are most likely only interested in the part about the glowing border, you should either use MahApps.Metro itself or see how I created a class GlowWindowBehavior which attaches glow borders to my custom ModernWindow class. It is hevily dependant on some internals of MahApps.Metro and the two dependency properties GlowBrush and NonActiveGlowBrush.
If you only want to include the glowing borders to your custom applications just reference MahApps.Metro and copy over my GlowWindowBehavior.cs and create a custom window class and adapt the references accordingly. This is a matter of 15 minutes at most.
This question and my answer have been accessed very frequently so I hope you will find my newest proper solution useful :)
Original post (February '13)
I have been working on such a library to copy the Visual Studio 2012 user interface. A custom chrome isn't that difficult but what you should take care of is this glowing border which is hard to implement. You could just say set the background color of your window to transparent and set the padding of the main grid to about 30px. A border around the grid could be colored and associated with a colored shadow effect but this approach forces you to set AllowsTransparency to true which drastically reduces visual performance of your application and this is something you definitely do not want to do!
My current approach to create such a window which just has a colored shadow effect on a border and is transparent but has no content at all. Evertime the position of my main window changes I just update the position of the window which holds the border. So in the end I am handling two windows with messages to fake that the border would be part of the main window. This was necessary because the DWM library doesn't provide a way to have a colored drop shadow effect for windows and I think Visual Studio 2012 does that similiar like I tried.
And to extend this post with more information: Office 2013 does that differently. The border around a window is just 1px thick and colored, yet the shadow is drawn by DWM with a code like this one here. If you can live without having blue/purple/green borders and just usual ones this is the approach I would choose! Just don't set AllowsTransparency to true, otherwise you have lost.
And here is a screenshot of my window with strange color to highlight what it looks like:
Here are some hints on how to start
Please keep in mind that my code is quite long, such that I will only be able to show you the basic things to do and you should be able to at least start somehow. First of all I'm going to assume that we have designed our main window somehow (either manually or with the MahApps.Metro package I tried out yesterday - with some modifications to the sourcecode this is really good(1)) and we are currently working to implement the glowing shadow border, which I will call GlowWindow from now on. The easiest approach is to create a window with the following XAML code
<Window x:Class="MetroUI.Views.GlowWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="GlowWindow"
Title="" Width="300" Height="100" WindowStartupLocation="Manual"
AllowsTransparency="True" Background="Transparent" WindowStyle="None"
ShowInTaskbar="False" Foreground="#007acc" MaxWidth="5000" MaxHeight="5000">
<Border x:Name="OuterGlow" Margin="10" Background="Transparent"
BorderBrush="{Binding Foreground, ElementName=GlowWindow}"
BorderThickness="5">
<Border.Effect>
<BlurEffect KernelType="Gaussian" Radius="15" RenderingBias="Quality" />
</Border.Effect>
</Border>
</Window>
The resulting window should look like the following picture.
The next steps are quite difficult - when our main window spawns we want to make the GlowWindow visible but behind the main window and we have to update the position of the GlowWindow when the main window is being moved or resized. What I suggest to prevent visual glitches that can AND will occur is to hide the GlowWindow during every change of either location or size of the window. Once finished with such action just show it again.
I have some method which is called in different situations (it might be a lot but just to get sure)
private void UpdateGlowWindow(bool isActivated = false) {
if(this.DisableComposite || this.IsMaximized) {
this.glowWindow.Visibility = System.Windows.Visibility.Collapsed;
return;
}
try {
this.glowWindow.Left = this.Left - 10;
this.glowWindow.Top = this.Top - 10;
this.glowWindow.Width = this.Width + 20;
this.glowWindow.Height = this.Height + 20;
this.glowWindow.Visibility = System.Windows.Visibility.Visible;
if(!isActivated)
this.glowWindow.Activate();
} catch(Exception) {
}
}
This method is mainly called in my custom WndProc I have attached to the main window:
/// <summary>
/// An application-defined function that processes messages sent to a window. The WNDPROC type
/// defines a pointer to this callback function.
/// </summary>
/// <param name="hwnd">A handle to the window.</param>
/// <param name="uMsg">The message.</param>
/// <param name="wParam">Additional message information. The contents of this parameter depend on
/// the value of the uMsg parameter.</param>
/// <param name="lParam">Additional message information. The contents of this parameter depend on
/// the value of the uMsg parameter.</param>
/// <param name="handled">Reference to boolean value which indicates whether a message was handled.
/// </param>
/// <returns>The return value is the result of the message processing and depends on the message sent.
/// </returns>
private IntPtr WindowProc(IntPtr hwnd, int uMsg, IntPtr wParam, IntPtr lParam, ref bool handled) {
// BEGIN UNMANAGED WIN32
switch((WinRT.Message)uMsg) {
case WinRT.Message.WM_SIZE:
switch((WinRT.Size)wParam) {
case WinRT.Size.SIZE_MAXIMIZED:
this.Left = this.Top = 0;
if(!this.IsMaximized)
this.IsMaximized = true;
this.UpdateChrome();
break;
case WinRT.Size.SIZE_RESTORED:
if(this.IsMaximized)
this.IsMaximized = false;
this.UpdateChrome();
break;
}
break;
case WinRT.Message.WM_WINDOWPOSCHANGING:
WinRT.WINDOWPOS windowPosition = (WinRT.WINDOWPOS)Marshal.PtrToStructure(lParam, typeof(WinRT.WINDOWPOS));
Window handledWindow = (Window)HwndSource.FromHwnd(hwnd).RootVisual;
if(handledWindow == null)
return IntPtr.Zero;
bool hasChangedPosition = false;
if(this.IsMaximized == true && (this.Left != 0 || this.Top != 0)) {
windowPosition.x = windowPosition.y = 0;
windowPosition.cx = (int)SystemParameters.WorkArea.Width;
windowPosition.cy = (int)SystemParameters.WorkArea.Height;
hasChangedPosition = true;
this.UpdateChrome();
this.UpdateGlowWindow();
}
if(!hasChangedPosition)
return IntPtr.Zero;
Marshal.StructureToPtr(windowPosition, lParam, true);
handled = true;
break;
}
return IntPtr.Zero;
// END UNMANAGED WIN32
}
However there is still an issue left - once you resize your main window the GlowWindow will not be able to cover the whole window with its size. That is if you resize your main window to about MaxWidth of your screen, then the widt of the GlowWindow would be the same value + 20 as I have added a margin of 10 to it. Therefore the right edge would be interrupted right before the right edge of the main window which looks ugly. To prevent this I used a hook to make the GlowWindow a toolwindow:
this.Loaded += delegate {
WindowInteropHelper wndHelper = new WindowInteropHelper(this);
int exStyle = (int)WinRT.GetWindowLong(wndHelper.Handle, (int)WinRT.GetWindowLongFields.GWL_EXSTYLE);
exStyle |= (int)WinRT.ExtendedWindowStyles.WS_EX_TOOLWINDOW;
WinRT.SetWindowLong(wndHelper.Handle, (int)WinRT.GetWindowLongFields.GWL_EXSTYLE, (IntPtr)exStyle);
};
And still we will have some issues - when you go with the mouse over the GlowWindow and left click it will be activated and get the focus which means it will overlap the main window which looks like this:
To prevent that just catch the Activated event of the border and bring the main window to the foreground.
How should YOU do this?
I suggest NOT to try this out - it took me about a month to achieve what I wanted and still it has some issues, such that I would go for an approach like Office 2013 does - colored border and usual shadow with the DWM API calls - nothing else and still it looks good.
(1) I have just edited some files to enable the border around the window which is disabled on Window 8 for me. Furthermore I have manipulated the Padding of the title bar such that it doesn't look that sqeezed inplace and lastly I have change the All-Caps property to mimic Visual Studio's way of rendering the title. So far the MahApps.Metro is a better way of drawing the main window as it even supports AeroSnap I couldn't implement with usual P/Invoke calls.
You can use this simple xaml code
<Window x:Class="VS2012.MainWindow"
xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation
xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml
Title="MainWindow"
Height="100" Width="200"
AllowsTransparency="True" WindowStyle="None" Background="Transparent">
<Border BorderBrush="DarkOrange" BorderThickness="1" Background="White" Margin="5">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" BlurRadius="5" Color="DarkOrange"/>
</Border.Effect>
</Border>
</Window>
This is called "Metro style" (Windows 8 style). I think that this Code Project article is interesting for you and it will help you.
You can try Elysium, which licensed under MIT license and included ApplicationBar and ToastNotification classes, or MetroToolKit, from codeplext, too.
This is a great tutorial about Elysium, I think that it helps you.
For shadow, just add a BitmapEffect to a Border from your Grid in XAML:
<Grid>
<Border BorderBrush="#FF006900" BorderThickness="3" Height="157" HorizontalAlignment="Left" Margin="12,12,0,0" Name="border1" VerticalAlignment="Top" Width="479" Background="#FFCEFFE1" CornerRadius="20, 20, 20, 20">
<Border.BitmapEffect>
<DropShadowBitmapEffect Color="Black" Direction="320" ShadowDepth="10" Opacity="0.5" Softness="5" />
</Border.BitmapEffect>
<TextBlock Height="179" Name="textBlock1" Text="Hello, this is a beautiful DropShadow WPF Window Example." FontSize="40" TextWrapping="Wrap" TextAlignment="Center" Foreground="#FF245829" />
</Border>
</Grid>
<Window x:Class="MyProject.MiniWindow"
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:MyProject"
mc:Ignorable="d"
WindowStyle="None"
Title="MiniWindow" Background="Transparent"
Height="200" Width="200"
>
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="0"
ResizeBorderThickness="4" />
</WindowChrome.WindowChrome>
<Grid Margin="0">
<Border BorderThickness="3">
<Border BorderThickness="1" Margin="0" BorderBrush="#ff007acc">
<Border.Effect>
<DropShadowEffect Color="#ff007acc" Direction="132" ShadowDepth="0" BlurRadius="8" />
</Border.Effect>
<Grid Background="#ff2d2d30">
</Grid>
</Border>
</Border>
</Grid>
I'm trying to obtain the same effect, my app is using .NET 4 and thus I cannot directly use WindowChrome (so, I'm using the Microsoft Windows Shell library to get the same).
In this thread it is correctly noted that using spy++ it can be seen that Visual Studio has four windows called VisualStudioGlowWindow to implement the glowing effect.
It has been already described in many places how the AllowsTransparency property to true can reduce the performances.
So, I tried to go the VS way and the result is not bad (at least, for me); no need to use blur or similar effect on the main window, I just had to fight a bit with some window states (focus/visible/hidden).
I've put all the needed stuff on github - hope this can help.

Categories