Powershell WPF StackPanel not updating correctly - wpf

I'm writing an 'idle launching screen' for my Powershell UI launch page, using a WPF XAML form and Powershell [Windows.Markup.XamlReader].
When launching an external script, the launch page goes into an 'idle' mode, which is when the 'idle launching screen' comes in.
An example of the 'idle launching screen' when working correctly:
Now the issue is: when launching an external WPF UI (including an external WPF Powershell script) for the first time, the 'idle launching screen' works perfectly fine. Yet, when closing that external WPF UI and re-opening a different one (still in the same PSSession), the 'idle launching screen' looks weird. As if the StackPanel it's inside goes all the way to the foreground ignoring any Opacity or ZIndex settings (example can be found at the imgur link below).
My WPF StackPanel:
<StackPanel x:Name="Launching" Visibility="Visible">
<StackPanel.Background>
<LinearGradientBrush EndPoint="0.5,1" MappingMode="RelativeToBoundingBox" StartPoint="0.5,0">
<GradientStop Color="LightBlue" Offset="0.077"/>
<GradientStop Color="Transparent" Offset="2"/>
</LinearGradientBrush>
</StackPanel.Background>
<StackPanel Margin="0,180,0,0" Height="200" Width="200" Background="Transparent">
<wfi:WindowsFormsHost Margin="50,-30,0,0">
<winForms:PictureBox x:Name="pictureBoxLoading">
</winForms:PictureBox>
</wfi:WindowsFormsHost>
<Label Content="Applicatie lanceren..." Width="115" Margin="0,-29,0,0"/>
</StackPanel>
</StackPanel>
Powershell code behind the form:
## Loading the .gif
$pictureBoxLoading.Image = [System.Drawing.Image]::Fromfile("C:\Images\rocket.gif")
## Triggers
$Launching.Visibility = [System.Windows.Visibility]::Visible
$Launching.Visibility = [System.Windows.Visibility]::Hidden
Video example of my issue:
https://imgur.com/a/UZyxH0A

The problem is caused by the WindowsFormsHost, because it's a WinForms object and not natively in WPF supported. Get it named (<wfi:WindowsFormsHost x:Name="Host"...) and hide it too. Then make it visible after the rest of your loadingscreen:
function hide {
$Launching.Visibility = [System.Windows.Visibility]::Hidden
$Host.Visibility = [System.Windows.Visibility]::Hidden
}
function show {
$Launching.Visibility = [System.Windows.Visibility]::Visible
$Host.Visibility = [System.Windows.Visibility]::Visible
}

Related

MahApps.Metro 0.13.1: Show window commands without display the titlebar

I am developing an application in WPF using MahApps.Metro 0.12.1. In this application I don't show the titlebar, staying visible minimize, maximize and close commands. Below I show the code:
<controls:MetroWindow xmlns:views="clr-namespace:View.Views"
xmlns:titleBar="clr-namespace:View.Views.TitleBar"
x:Class="View.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
GlowBrush="{DynamicResource AccentColorBrush}"
ShowWindowCommandsOnTop="False"
ShowTitleBar="False"
Title="MainWindow" Height="400" Width="600"
AllowsTransparency="False">
<Grid>
...
</Grid>
The problem arises when I upgrade to the version 0.13.1 of MathApps.Metro, where these commands are not displayed, forcing me to re-establish the titlebar to display the commands again ShowTitleBar="True" and this is what I do not want: display the titlebar.
I was looking at the release notes of MathApps.Metro 0.13.1 and reports that changes were made to the section of the titlebar​​, but no further details are given.
My questions are: Is there a simple way to display the minimize, maximize and close commands without showing the title bar? What is the best way to do this?
thanks
you can put the window buttons directly in your main window like this
<Grid>
<!-- the window button commands -->
<Controls:WindowButtonCommands Panel.ZIndex="1"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Height="{Binding TitlebarHeight, Mode=OneWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Controls:MetroWindow}}}" />
...
</Grid>
hope that helps
Is there a simple way to display the minimize, maximize and close commands without showing the title bar? What is the best way to do this?
Actually not very simple, but possible. Basically you need to create your own Style template and override the ContentPresenter for your window to do so.
You may take a look at this question.
Besides that, this post will guide you through the process of designing your own titlebar.

In WPF Gradient Button pulses between the default color and new gradient once clicked - how to stop

This is a very annoying artifact I am noticing of WPF and I was curious what I could potentially be doing wrong as I am doing what appears to be simple code in WPF XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ExampleShapes.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="400" Height="400">
<Grid x:Name="LayoutRoot">
<Button Margin="50,50,50,50" Content="I pulse when clicked Why?">
<Button.Background>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FF0C0B0B" Offset="1"/>
<GradientStop Color="#FFBF5656"/>
</LinearGradientBrush>
</Button.Background>
</Button>
</Grid>
It appears that there are some defaults that are in .NET that I am unaware of with events of the MouseOver and Click that I DO NOT WANT. I don't mind that when the mouse hovers that it changes the color of the gradient to the default but when I remove it it changes back. However even before applying underlying C# code for the 'CLICK' event (not in example) it assumes a 'pulsing' behavior of going between my specified gradient and the default. This is also true with a simple color. What gives?
For further info I am designing on a Windows 7 64 bit box with Visual Studio 2010 and Expression Blend 3 using .NET 4.0 for VS2010 unsure for EB3 as it's an older copy and they Both do this. Is there a simple way to change the default behavior or do I have to set up a new user template for the button?
Any help is much appreciated thanks!
It appears to have something to do with the Focused style for the Button. I am guessing the default focused style alternates between the normal and mouseover backgrounds, which is causing the "pulsing" behavior.
Clicking the button sets it as focused, but you can also achieve the same effect by simply tabbing to the button.
Edit
Looking into this a bit more and it seems to be the default for the Aero theme for any element that has input focus. You can set the button's Focusable="False", however then you can't tab to the button or hit Enter on it (can still click it though), and personally I hate applications that I can't navigate with the keyboard.
To avoid the flashing when clicked, you can set focus to another control at the end of your click event, however the effect will still occur when you tab to the button.

Styling RadChart

I am trying to style a RadChart. It is a bargraph and I want to change the default colors of the bars. So I used the RadChart.PaletteBrushes and defined SolidBrush colors(Found this method in the following link : http://www.telerik.com/help/wpf/radchart-styling-and-appearance-styling-chart-series.html) as follows:
<telerik:RadChart Background="Transparent" HorizontalContentAlignment="Center" HorizontalAlignment="center">
<telerik:RadChart.PaletteBrushes>
<SolidColorBrush Color="#FF0B3F74"/>
<SolidColorBrush Color="#FF721111"/>
<SolidColorBrush Color="#FFA1720B"/>
</telerik:RadChart.PaletteBrushes>
</telerik:RadChart>
But now, an exception as follows occurs while running the application :
'System.Windows.Media.SolidColorBrush' must have IsFrozen set to false to modify.
This exception occurs randomly. Also, in the stack trace, there is a mention of RadTransition Control too. Why could this error be occuring? How can it be solved?
We also had the same problem, but with a variety of controls. After trading info with Microsoft, they said there was a bug in the Freeze implementation (fix coming in .NET 4.5, perhaps). In the meantime, we now freeze brushes on creation.
Add this namespace to your XAML:
xmlns:po="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options"
Then add po:Freeze=true to your brushes:
<SolidColorBrush x:Key="SearchGridHeaderBrush" Color="{StaticResource DefaultHeaderColor}" po:Freeze="true" />

Giving a stackPanel the same LinearGradientBrush as the toolbar has by default

I have two ToolBars side by side (I had to do that so I could align buttons right and left)
But now, I have to add some text that can be aligned right left or center between both toolbars. I added the text in a TextBlock inside a StackPanel disposed on a Grid at the second position (between the toolbars) and, of course, it created a gap between both toolbars (A stackPanel doesn't have the same style as a toolbar, of course).
I would like to replicate the toolbar LinearGradientBrush on my stackpanel so it looks the same as my toolbar does. the point is to make the thing look like ONE toolbar.
Is there a way to get the ToolBar Style or to recreate it with a LinearGradientBrush definition, and if so, how?
Here's one way you could do it. Say one of your toolbars' name is "toolBar." Bind the Background property on the StackPanel to the Background property on the ToolBar as such:
<StackPanel Background="{Binding Path=Background, ElementName=toolBar}" />
Hope that helps! :)
EDIT:
You can check out the control template for the ToolBar here.
The LinearGradientBrush used looks as such:
<LinearGradientBrush x:Key="DarkBrush" StartPoint="0,0" EndPoint="0,1">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="#FFF" Offset="0.0"/>
<GradientStop Color="#AAA" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
In the event you just wanted to use this instead of binding. :)
The default templates and styles are available on MSDN, you could probably extract the relevant bits from there.
I found an issue when doing this exact same thing in an application. When running the same application on an XP machine as I did a Vista machine, I found that there was a 2 pixel difference in the height between the two toolbars.
To get around this, I ended up creating one StackPanel which housed the two tool bar objects (setting the background to be transparent).
This ensured that the look and feel was the same between the two OS's (at the time the company was running both) and will also aid you in the event that one of your toolbars grow in height without the other.

WPF Controls Dll question

I've started work on a WPF controls dll which will be referenced from winforms applications.
My first control in this project is a simple container control. It's purpose in life is to provide a modaless, transparent docking window to the Winforms app.
My problem with this control is that I can't get it to move when I try to drag it. I can move it if I don't put it into a .dll. Inside the dll, Canvas.GetLeft - returns an invalid number, and I don't know how to fix this.
Here's the bulk of the XAML for this control:
<Grid Height="Auto">
<Grid.Resources>
<LinearGradientBrush x:Key="BackBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#C4000000"/>
<GradientStop Offset="1" Color="#66000000"/>
<GradientStop Color="#61000000" Offset="0.50400000810623169"/>
</LinearGradientBrush>
</Grid.Resources>
<Border Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Margin="0,0,0,0" BorderBrush="#FF000000" BorderThickness="2,2,2,2" Background="{StaticResource BackBrush}" Opacity="1" CornerRadius="8,8,8,8">
<StackPanel Background="{x:Null}" Opacity="1" Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Top" x:Name="spWhatAreYouDoing">
<ContentControl></ContentControl>
</StackPanel>
</Border>
<Thumb Background="{x:Null}" Opacity="0" DragDelta="onDragDelta" x:Name="panelthumb"/>
</Grid>
I've hooked the Thumb's onDragDelta event in the code behind and use that to drag this window around. This works fine when I use it in the same .exe.
public void onDragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
Canvas.SetLeft(this, Canvas.GetLeft(this) + e.HorizontalChange);
Canvas.SetTop(this, Canvas.GetTop(this) + e.VerticalChange);
}
When I take this same code out of the .exe and place it into a .dll then reference that .dll and use the control from my exe - it won't drag anymore. The window displays but won't move.
The reason it won't be moved is because Canvas.GetLeft(this) is returning an invalid number. Why? Although the destination for this control is usage by a Winforms app, I find this same behavior when I use it from a WPF app without any ElementHost intervention.
Edit - when I host this control directly within my Winforms app using ElementHost I can move the window. But window transparency is lost. And so the entire reason for moving to WPF for this form is invalid.
So I have done this wrong - what is the right way to call GetLeft from within a control hosted from a .dll?
I suggest you first host the WPF control inside a WinForm. Disable all the border properties of the WinForm...so your control looks as if it is all by itself. Then use this WinForm as the primary means of using your control.
This way you get access to all the related functionality.
In a gist >>> XAML inside a standalone Winforms host. >>> Winform to be used as control in other Winforms.
Whew. I found this link, and it is the answer I needed to get this to work.
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/281a8cdd-69a9-4a4a-9fc3-c039119af8ed
Instead of using Canvas.GetLeft, I am now using code which obtains the absolute locatin of this control and then raises an event which containers can monitor to know when to move:
'// Get absolute location on screen of upper left corner of button
Dim locationFromScreen As Point = Me.PointToScreen(New Point(0, 0))
'// Transform screen point to WPF device independent point
Dim source As PresentationSource = PresentationSource.FromVisual(Me)
Dim targetPoints As System.Windows.Point = source.CompositionTarget.TransformFromDevice.Transform(locationFromScreen)
Dim left As Double = targetPoints.X
Dim top As Double = targetPoints.Y
left += e.HorizontalChange
top += e.VerticalChange
Canvas.SetLeft(Me, left)
Canvas.SetTop(Me, top)
'spread the news
PaletteMoved(New DockingPaletteEventArgs(left, top, e.HorizontalChange, e.VerticalChange))

Resources