Created
February 10, 2011 08:53
-
-
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
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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