Skip to content

Instantly share code, notes, and snippets.

@jeffwilcox
Created February 10, 2011 08:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeffwilcox/820168 to your computer and use it in GitHub Desktop.
Save jeffwilcox/820168 to your computer and use it in GitHub Desktop.
Simple stab at a base window class that doesn't use popup but depends on a frame
<Style TargetType="layoutToolkit:HeaderedContentControl">
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="layoutToolkit:HeaderedContentControl">
<StackPanel>
<ContentPresenter
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Cursor="{TemplateBinding Cursor}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Cursor="{TemplateBinding Cursor}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="jw:MessageBoxWindow">
<Setter Property="LeftButtonText" Value="ok"/>
<Setter Property="RightButtonText" Value="cancel"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="VerticalContentAlignment" Value="Top"/>
<Setter Property="FontFamily" Value="{StaticResource PhoneFontFamilyNormal}"/>
<Setter Property="FontSize" Value="{StaticResource PhoneFontSizeNormal}"/>
<Setter Property="Foreground" Value="{StaticResource PhoneForegroundBrush}"/>
<Setter Property="Background" Value="{StaticResource PhoneChromeBrush}"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="jw:MessageBoxWindow">
<Grid
CacheMode="BitmapCache"
Background="{TemplateBinding Background}"
VerticalAlignment="Top"
HorizontalAlignment="Stretch"
fam:TiltEffect.IsTiltEnabled="True">
<StackPanel Margin="12,12,12,18">
<TextBlock
Style="{StaticResource PhoneTextLargeStyle}"
Text="{TemplateBinding Header}"
FontFamily="{StaticResource PhoneFontFamilySemiBold}"
TextWrapping="Wrap"
HorizontalAlignment="Left"/>
<TextBlock
Style="{StaticResource PhoneTextNormalStyle}"
Margin="12,24,12,24"
Text="{TemplateBinding Content}"
TextWrapping="Wrap"
HorizontalAlignment="Left"/>
<CheckBox
Content="{TemplateBinding CheckBoxContent}"
IsChecked="{TemplateBinding IsChecked}"
Visibility="{TemplateBinding CheckBoxVisibility}"
Margin="0,0,0,6"/>
<Grid HorizontalAlignment="Stretch" Margin="0,6,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Button
x:Name="_left"
Content="{TemplateBinding LeftButtonText}"
Grid.Column="0"
Visibility="{TemplateBinding LeftButtonVisibility}"/>
<Button
x:Name="_right"
Content="{TemplateBinding RightButtonText}"
Visibility="{TemplateBinding RightButtonVisibility}"
Grid.Column="1"/>
</Grid>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="jw:WilcoxTransitionFrame">
<Setter Property="Background" Value="{StaticResource PhoneBackgroundBrush}"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="jw:WilcoxTransitionFrame">
<Grid Margin="{TemplateBinding Margin}"
x:Name="ClientArea"
Background="{TemplateBinding Background}">
<Image x:Name="AnalyticsImage" VerticalAlignment="Top" Opacity="0"/>
<ContentPresenter
x:Name="FirstContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<ContentPresenter
x:Name="SecondContentPresenter"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Grid x:Name="OverlayGrid"/><!-- VerticalAlignment="Top" -->
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
using System;
using System.Windows;
using System.Windows.Controls;
namespace JeffWilcox.Controls
{
public class MessageBoxWindow : WindowBase
{
private Button _button1;
private Button _button2;
#region public object CheckBoxContent
/// <summary>
/// Gets or sets the checkbox content.
/// </summary>
public object CheckBoxContent
{
get { return GetValue(CheckBoxContentProperty) as object; }
set { SetValue(CheckBoxContentProperty, value); }
}
/// <summary>
/// Identifies the CheckBoxContent dependency property.
/// </summary>
public static readonly DependencyProperty CheckBoxContentProperty =
DependencyProperty.Register(
"CheckBoxContent",
typeof(object),
typeof(MessageBoxWindow),
new PropertyMetadata(null, OnCheckBoxContentPropertyChanged));
/// <summary>
/// CheckBoxContentProperty property changed handler.
/// </summary>
/// <param name="d">MessageBoxWindow that changed its CheckBoxContent.</param>
/// <param name="e">Event arguments.</param>
private static void OnCheckBoxContentPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MessageBoxWindow source = d as MessageBoxWindow;
object value = e.NewValue as object;
if (value == null)
{
source.CheckBoxVisibility = Visibility.Collapsed;
}
else
{
source.CheckBoxVisibility = Visibility.Visible;
}
}
#endregion public object CheckBoxContent
#region public Visibility CheckBoxVisibility
/// <summary>
/// Gets or sets the visibility of the check box control. Not intended for regular use.
/// </summary>
public Visibility CheckBoxVisibility
{
get { return (Visibility)GetValue(CheckBoxVisibilityProperty); }
set { SetValue(CheckBoxVisibilityProperty, value); }
}
/// <summary>
/// Identifies the CheckBoxVisibility dependency property.
/// </summary>
public static readonly DependencyProperty CheckBoxVisibilityProperty =
DependencyProperty.Register(
"CheckBoxVisibility",
typeof(Visibility),
typeof(MessageBoxWindow),
new PropertyMetadata(Visibility.Collapsed));
#endregion public Visibility CheckBoxVisibility
#region public bool? IsChecked
/// <summary>
/// Gets or sets the is checked property.
/// </summary>
public bool? IsChecked
{
get { return (bool?)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
/// <summary>
/// Identifies the IsChecked dependency property.
/// </summary>
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register(
"IsChecked",
typeof(bool?),
typeof(MessageBoxWindow),
new PropertyMetadata(false));
#endregion public bool? IsChecked
#region public string LeftButtonText
/// <summary>
///
/// </summary>
public string LeftButtonText
{
get { return GetValue(LeftButtonTextProperty) as string; }
set { SetValue(LeftButtonTextProperty, value); }
}
/// <summary>
/// Identifies the LeftButtonText dependency property.
/// </summary>
public static readonly DependencyProperty LeftButtonTextProperty =
DependencyProperty.Register(
"LeftButtonText",
typeof(string),
typeof(MessageBoxWindow),
new PropertyMetadata(null, OnLeftButtonTextPropertyChanged));
/// <summary>
/// LeftButtonTextProperty property changed handler.
/// </summary>
/// <param name="d">MessageBoxWindow that changed its LeftButtonText.</param>
/// <param name="e">Event arguments.</param>
private static void OnLeftButtonTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MessageBoxWindow source = d as MessageBoxWindow;
string value = e.NewValue as string;
source.LeftButtonVisibility = value == null ? Visibility.Collapsed : Visibility.Visible;
}
#endregion public string LeftButtonText
#region public string RightButtonText
/// <summary>
///
/// </summary>
public string RightButtonText
{
get { return GetValue(RightButtonTextProperty) as string; }
set { SetValue(RightButtonTextProperty, value); }
}
/// <summary>
/// Identifies the RightButtonText dependency property.
/// </summary>
public static readonly DependencyProperty RightButtonTextProperty =
DependencyProperty.Register(
"RightButtonText",
typeof(string),
typeof(MessageBoxWindow),
new PropertyMetadata(null, OnRightButtonTextPropertyChanged));
/// <summary>
/// RightButtonTextProperty property changed handler.
/// </summary>
/// <param name="d">MessageBoxWindow that changed its RightButtonText.</param>
/// <param name="e">Event arguments.</param>
private static void OnRightButtonTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MessageBoxWindow source = d as MessageBoxWindow;
string value = e.NewValue as string;
source.RightButtonVisibility = value == null ? Visibility.Collapsed : Visibility.Visible;
}
#endregion public string RightButtonText
#region public Visibility LeftButtonVisibility
/// <summary>
///
/// </summary>
public Visibility LeftButtonVisibility
{
get { return (Visibility)GetValue(LeftButtonVisibilityProperty); }
set { SetValue(LeftButtonVisibilityProperty, value); }
}
/// <summary>
/// Identifies the LeftButtonVisibility dependency property.
/// </summary>
public static readonly DependencyProperty LeftButtonVisibilityProperty =
DependencyProperty.Register(
"LeftButtonVisibility",
typeof(Visibility),
typeof(MessageBoxWindow),
new PropertyMetadata(Visibility.Collapsed));
#endregion public Visibility LeftButtonVisibility
#region public Visibility RightButtonVisibility
/// <summary>
///
/// </summary>
public Visibility RightButtonVisibility
{
get { return (Visibility)GetValue(RightButtonVisibilityProperty); }
set { SetValue(RightButtonVisibilityProperty, value); }
}
/// <summary>
/// Identifies the RightButtonVisibility dependency property.
/// </summary>
public static readonly DependencyProperty RightButtonVisibilityProperty =
DependencyProperty.Register(
"RightButtonVisibility",
typeof(Visibility),
typeof(MessageBoxWindow),
new PropertyMetadata(Visibility.Collapsed));
#endregion public Visibility RightButtonVisibility
public event EventHandler LeftButtonClick;
public event EventHandler RightButtonClick;
public MessageBoxWindow()
: base()
{
DefaultStyleKey = typeof(MessageBoxWindow);
}
private bool _hasAnimatedIn;
public static MessageBoxWindow Show(string text)
{
return Show(text, null, "Ok");
}
public static MessageBoxWindow Show(string text, string caption, string leftButton)
{
return Show(text, caption, leftButton, null);
}
public static MessageBoxWindow Show(string text, string caption, string leftButton, string rightButton)
{
return Show(text, caption, leftButton, rightButton, null);
}
public static MessageBoxWindow Show(string text, string caption, MessageBoxButton buttons)
{
string left = "ok";
string right = buttons == MessageBoxButton.OKCancel ? "cancel" : null;
return Show(text, caption, left, right);
}
private bool _clicked;
public static MessageBoxWindow Show(string text, string caption, string leftButton, string rightButton, string checkBoxContent)
{
var win = new MessageBoxWindow();
win.Content = text;
win.Header = caption;
win.LeftButtonText = leftButton;
win.RightButtonText = rightButton;
win.CheckBoxContent = checkBoxContent;
win.InsertIntoFrame();
return win;
}
public override void OnApplyTemplate()
{
if (_button1 != null)
{
_button1.Click -= OnClick;
}
if (_button2 != null)
{
_button2.Click -= OnClick;
}
base.OnApplyTemplate();
_button1 = GetTemplateChild("_left") as Button;
if (_button1 != null)
{
_button1.Click += OnClick;
}
_button2 = GetTemplateChild("_right") as Button;
if (_button2 != null)
{
_button2.Click += OnClick;
}
}
private void OnClick(object sender, RoutedEventArgs e)
{
if (sender == _button1)
{
var handler = LeftButtonClick;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
else if (sender == _button2)
{
var handler = RightButtonClick;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
CloseWindow();
}
}
}
using System;
using System.Windows.Controls;
using Delay;
namespace JeffWilcox.Controls
{
using Microsoft.Phone.Controls;
public class WilcoxTransitionFrame : HybridOrientationChangesFrame
{
private const string OverlayTemplatePartName = "OverlayGrid";
private const string AnalyticsImageTemplatePartName = "AnalyticsImage";
public Grid OverlayGrid { get; private set; }
public Image AnalyticsImage { get; private set; }
public event EventHandler HaveOverlayGrid;
public WilcoxTransitionFrame() : base()
{
DefaultStyleKey = typeof (WilcoxTransitionFrame);
}
public override void OnApplyTemplate()
{
OverlayGrid = GetTemplateChild(OverlayTemplatePartName) as Grid;
AnalyticsImage = GetTemplateChild(AnalyticsImageTemplatePartName) as Image;
if (OverlayGrid != null && HaveOverlayGrid != null)
{
// This is a simple way to message about this.
Dispatcher.BeginInvoke(() => HaveOverlayGrid(this, EventArgs.Empty));
}
base.OnApplyTemplate();
}
}
}
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
namespace JeffWilcox.Controls
{
// Based upon Headered Content Control as it often comes up in these templates.
public class WindowBase : HeaderedContentControl
{
private PhoneApplicationPage _page;
private bool _transitionedIn;
private Panel _templateRoot;
public event EventHandler PressedBack;
private Grid _overlay;
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_templateRoot = MoreVisualTreeExtensions.FindFirstChildOfType<Panel>(this);
if (_templateRoot == null)
{
throw new InvalidOperationException("Must include a Panel in the root of the template.");
}
if (!_transitionedIn)
{
var @in = GetTransitionIn();
if (@in != null)
{
var transition = @in.GetTransition(_templateRoot);
transition.Completed += (x, xe) => transition.Stop();
transition.Begin();
}
_transitionedIn = true;
}
}
private void BuildOverlay()
{
var bg = (Color)Resources["PhoneBackgroundColor"];
_overlay = new Grid();
_overlay.IsHitTestVisible = true;
_overlay.Background = new SolidColorBrush(Color.FromArgb(0xa0, bg.R, bg.G, bg.B));
}
protected void InsertIntoVisualTree(Panel parentPanel)
{
BuildOverlay();
parentPanel.Children.Add(_overlay);
parentPanel.Children.Add(this);
// WARNING: This version will not attach to page back button
// key presses and could fail ingestion.
}
protected void InsertIntoFrame()
{
IExposeRootFrame ie = Application.Current as IExposeRootFrame;
if (ie != null)
{
WilcoxTransitionFrame wtf = ie.RootFrame;
InsertIntoVisualTree(wtf.OverlayGrid);
_page = wtf.Content as PhoneApplicationPage;
if (_page != null)
{
_page.BackKeyPress += OnBackKeyPress;
}
}
else throw new InvalidOperationException("Root must be of WilcoxTransitionFrame type.");
}
private void OnBackKeyPress(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = true;
var handler = PressedBack;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
CloseWindow();
}
protected void CloseWindow()
{
// Remove from the parent visual tree.
var me = this;
if (_page != null)
{
_page.BackKeyPress -= OnBackKeyPress;
_page = null;
}
Action removeVisualFromParent = () =>
{
Dispatcher.BeginInvoke(() =>
{
Panel p = me.Parent as Panel;
if (p != null)
{
p.Children.Remove(me);
}
});
};
Action removeOverlay = () =>
{
Grid overlay = _overlay;
_overlay = null;
if (overlay != null)
{
Panel p = overlay.Parent as Panel;
if (p != null)
{
p.Children.Remove(overlay);
}
}
};
Action removeVisuals = () =>
{
removeOverlay();
removeVisualFromParent();
};
// Animate.
var @out = GetTransitionOut();
if (@out != null)
{
var transition = @out.GetTransition(_templateRoot);
transition.Completed += (x, xe) =>
{
me.Opacity = 0;
transition.Stop();
removeVisuals();
};
transition.Begin();
}
else
{
removeVisuals();
}
}
protected virtual TransitionElement GetTransitionIn()
{
return new SwivelTransition
{
Mode = SwivelTransitionMode.BackwardIn,
};
}
protected virtual TransitionElement GetTransitionOut()
{
return new SwivelTransition
{
Mode = SwivelTransitionMode.BackwardOut,
};
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment