VisualBrush of a Window in another Window - wpf

So basically, the MainWindow opens a second Window, let's say OptionsWindow. So in the OptionsWindow I want to show a visual of the MainWindow. I tried this, but didn't work:
<Rectangle Grid.Row="1" Margin="3" Height="100">
<Rectangle.Fill>
<VisualBrush Visual="{Binding Application.Current.MainWindow}" />
</Rectangle.Fill>
</Rectangle>
Any help greatly appreciated.
EDIT:
I found the obvious answer:
windowPreview.Visual = Application.Current.MainWindow;
The only weird thing is that it calls the Loaded event of the MainWindow again and I have some code there that should only run when the MainWindow first loads. I though it would just show the current instance of the MainWindow. Any workaround on this?

If you put the load code in the constructor for the MainWindow that should only get called once per instance.
I'm not sure if it is a bug that WPF calls the Load event more than once for any given window, but it sounds like it might be by design for cases where a user closes and reloads the window...

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.

SurfaceScrollViewer: getting touch on nested children

I have the following piece of code, which is part of a WPF 4 UserControl:
<Popup x:Name="CantoPopup" IsOpen="False" PlacementRectangle="50,-100,500,120"
AllowsTransparency="True" PopupAnimation="Fade"
StaysOpen="True" Width="500" Height="120">
<Border BorderBrush="#FF120403" BorderThickness="1" CornerRadius="10" Background="#FF9350">
<s:SurfaceScrollViewer x:Name="IndexScroller" Width="500" Height="120" Margin="10" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Visible">
<DockPanel x:Name="InnerIndexPanel" />
</s:SurfaceScrollViewer>
</Border>
</Popup>
The DockPanel is then populated in the code-behind with a collection of TextBlocks. Basically, I am trying to build a scrollable horizontal list of touchable items.
Now, I would like to detect which textblock was touched by the user. However, neither adding a TouchDown event handler to the TextBlocks nor using TouchExtensions to handle tap gestures worked. Can someone please point me in the right direction?
Under the covers, Popup creates another hwnd to render its content into. This is different from all other WPF controls. You need to register this hwnd with the Surface SDK so it will start sending touch events to it. Use this to do that: http://msdn.microsoft.com/en-us/library/microsoft.surface.presentation.input.touchextensions.enablesurfaceinput.aspx
I found out that the point is that the Popup component has some peculiarities :) In this case, it seems that it did not detect neither TouchDown events nor PreviewTouchDown ones. Therefore, I resorted to creating a UserControl made of a Canvas containing the code above and then making such control visible on top of the rest whenever I needed the popup to open. I do not know whether this is the best solution, but now it reacts as expected.

Rendering Time of Image Defined in Xaml

I have a problem about displaying Image on Screen.
I created new WPF project in VS2010 and added the following code in MainWindow.xaml.
<Window
...>
<Grid>
<Grid.Background>
<ImageBrush ImageSource="image.jpg">
</Grid.Background>
</Grid>
</Window>
But displaying image.jpg is not that fast as I expected, and It doesn't show image.jpg immediately.
First it shows Empty Screen for a while(during rendering time, I think) and after that shows image.jpg.
How can I avoid the Empty Screen.
Please help me.
Thank you.
I think ImageSource.DownloadCompleted event, PriorityBinding and Binding.IsAsync will help you here...
http://social.msdn.microsoft.com/Forums/en-AU/wpf/thread/b3dc9baa-4cf6-49ed-a316-b9fb1cd29516

How to make a windows slide out using WPF( expression Blend 4and C#)

I am trying to figure out how to connect windows so the slide out using a small button from the left or right of a main window. What I am trying to do is create a main form with 2 windows connected to it. For one of the windows when the user presses a button on the main window it makes the window seem to slide out rather than pop up. Here is where I got the idea http://www.youtube.com/watch?v=CVlSj0yr3rg&feature=related ..The user then changes a value and the main windows is updated with new information. Honestly I have finished writing all my code and got everything working in Windows Forms in visual studio 2010 (with pop up windows).But I am thinking to make a more appealing gui WPF is the way to go, plus I like learning about it. If you have any forums, tutorials or general answers that would be great.
OK, so judging from the video you really want some kind of expander that opens and not a Window. A Window is an area with border, and the standard buttons and titlebar at the top.
This can be done with a grid with two columns. One is set to Auto width, one is set to * width. In the Auto sized one you can put your expanding content, and have your always visible content in the other.
The simple way to do this:
The Xaml
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:StackOverflow"
x:Class="MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" MinWidth="7"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid x:Name="ExpandoGrid"/>
<Button Content="..." Grid.Column="0" HorizontalAlignment="Right" Margin="0" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" Width="6" Height="40" Click="Button_Click"/>
<Grid x:Name="OtherContentGrid" Grid.Column="1" HorizontalAlignment="Left" Height="100" Margin="-7,0,0,0" VerticalAlignment="Top" Width="100"/>
</Grid>
</Window>
The Code-behind
Imports System.Collections.ObjectModel
Class MainWindow
Public Sub New()
InitializeComponent()
End Sub
Private Sub Button_Click(ByVal sender as Object, ByVal e as System.Windows.RoutedEventArgs)
If Me.ExpandoGrid.Width = 7 Then Me.ExpandoGrid.Width = 200 Else Me.ExpandoGrid.Width = 7
End Sub
End Class
This is by no means the complete way, or the best way. It is one of the simplest to implement though. A better way would be with a ViewModel which would handle the state of the expanded area, along with some animations to make it a smooth transition. If you want the sliding behaviour that is done in that video, animations are where it is at. If you are using Blend, then you have the right tool for animations.
Personally I would have this Windows ViewModel have a property (lets call it DrawerExpanded as Boolean) that a customized Expander would bind its IsExpanded property to. I would then create an open animation that sets the width of the content in the expander, and a close animation that sets the width to 0. Additionally, in each of these I would probably include setting the visibility and opacity to make the effect better and not weird. So lets say expand animation sets Width to 350 at .5 seconds, Visibility to visible at .5 seconds, and then opacity from 0 to 100 from .5 seconds to .7 seconds. That way the drawer slides out and the content fades quickly into view.
If you want a code example of that, you may have to give me a few mins.
I would really just take the easy/friendly route of creating Visual States in Expression Blend. There's basically just an "in state" and "out state", and an InteractionTrigger that allows the control to trigger the state change. Its awesome and extremely user friendly.
No code behind :) Hope it helps you!
As a bonus, you can easily add transition effects just like in a powerpoint. The xaml code gets pretty verbose, but working in Blend allows you to use the IDE to manage everything you add visually.
You can even use the Interaction Trigger to toggle between visibility states of the other controls, rather than writing converters, etc.

How to display a busy message over a wpf screen

Hey,
I have a WPF application based on Prism4. When performing slow operations, I want to show a busy screen. I will have a large number of screens, so I'm trying to build a single solution into the framework rather than adding the busy indicator to each screen.
These long running operations run in a background thread. This allows the UI to be updated (good) but does not stop the user from using the UI (bad). What I'd like to do is overlay a control with a spinning dial sort of thing and have that control cover the entire screen (the old HTML trick with DIVs). When the app is busy, the control would display thus block any further interaction as well as showing the spinny thing.
To set this up, I thought I could just have my app screen in a canvas along with the spinny thing (with a greater ZIndex) then just make the spinny thing visible as required.
This, however, is getting hard. Canvases do not seem well set up for this and I think I might be barking up the wrong tree.
I would appreciate any help. Thanks.
I have done this with a few programs. Here it is in a nutshell:
(This is easiest with MVVM. It has been so long since I used the codebehid for things like this I can't really say if there is a good way to do it.)
Create a border on your Main Window. I usually make it black with a 50% transparency. Add a grid to it, and put whatever you want inside to tell users it is busy. Size the border and the controls inside it to fill the screen.
Create a property on your main ViewModel for IsBusy as boolean. Initialize it as False. Bind the Visibility property of the Busy Border to that property.
Next, make a converter class for Busy(Boolean) to Visibility. Write the logic into that so that when value is True, Then visibility is Visible, when value is false, visibility is collapsed. ( http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx ).
Back on the border, add your converter to the binding. Add code to the ViewModel for each of your Pages or Views that calls back to that property and sets it to true when your other thread is busy.
Cory
Edit:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Grid>
<Border BorderBrush="Black" BorderThickness="1" Background="#80000000" Visibility="Collapsed">
<Grid>
<TextBlock Margin="0" TextWrapping="Wrap" Text="Busy...Please Wait" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="26.667" FontWeight="Bold" Foreground="#7EFFFFFF"/>
</Grid>
</Border>
<DockPanel x:Name="LayoutRoot">
<CheckBox Content="CheckBox" VerticalAlignment="Top"/>
<TextBlock TextWrapping="Wrap"><Run Text="TextBlock"/></TextBlock>
<UserControl x:Name="ViewViewView"/>
</DockPanel>
</Grid>
Look at this WPF toolkit with a busy indicator: https://github.com/xceedsoftware/wpftoolkit/wiki/BusyIndicator
I do this by simply displaying a dialog (so the user cannot interact with anything else and it will be displayed on top) then handle the Closing event (as the user could press Alt-F4) to see if the operation has finished otherwise I cancel the closing event:
myWaitWindow.ShowDialog(); // this can be borderless window with a spinny thing
void Window_Closing(object sender, CancelEventArgs e)
{
if(this.myOperation.IsRunning) // you would have to have some way to see when your operation has finished
e.Cancel = true;
}

Resources