|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Chapters
Services
Feature Zones
|
IntroductionThe BackgroundArticles about the other two controls, the Using the codeThe The The content of an Outlook Section can be any arbitrary control, but In minimized mode, the The
Interaction between template and codeVarious dependency properties enable interaction with the template and the code. Usually, the XAML gets the information from the code using <ToggleButton Style="{StaticResource buttonInSection}" Width="18"
IsChecked="{Binding IsOverflowVisible,
RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" >
<ToggleButton.Content>
<Path VerticalAlignment="Center" HorizontalAlignment="Center"
Fill="{DynamicResource ImageBrush}"
Stroke="White" Data="M2,4 L5,7 8,4"/>
</ToggleButton.Content>
<ToggleButton.ContextMenu>
<ContextMenu IsOpen="{Binding IsOverflowVisible,
RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"
ItemsSource="{TemplateBinding OverflowMenuItems}">
</ContextMenu>
</ToggleButton.ContextMenu>
</ToggleButton>
<Style TargetType="{x:Type ButtonBase }" x:Key="buttonStyle">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border Background="{TemplateBinding Background}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Focusable="False"
x:Name="border"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{DynamicResource BorderBrush}" >
<ContentPresenter Focusable="False"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalAlignment="Center" Horizontal
Alignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background"
Value="{DynamicResource HighlightButtonGradientBrush}"
TargetName="border"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background"
Value="{DynamicResource SelectedButtonGradientBrush}"
TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Here, the In other cases, when a button click has to cause an action, for instance, when a splitter button is pressed, it will raise a command: <Button x:Name="resizeButton" Width="4" DockPanel.Dock="Right"
Visibility="{Binding CanResize,RelativeSource={RelativeSource TemplatedParent},
Converter={StaticResource visibleConverter}}"
Cursor="SizeWE"
ClickMode="Press" Command="local:OutlookBar.ResizeCommand">
<Button.Template>
<ControlTemplate>
<Border Background="Transparent"/>
</ControlTemplate>
</Button.Template>
</Button>
The command itself is defined as follows: /// <summary>
/// Start to resize the Width of the OutlookBar
/// (used for the xaml template to initiate resizing).
/// </summary>
public static RoutedUICommand ResizeCommand
{
get { return resizeCommand; }
}
private static RoutedUICommand resizeCommand =
new RoutedUICommand("Resize",
"ResizeCommand", typeof(OutlookBar));
At the initializer, a method is associated to this command: CommandBindings.Add(new CommandBinding(ResizeCommand, ResizeCommandExecuted));
Therefore, when the Resize button is clicked, it sends the A third way to interact is to use a specific control that is defined in the XAML in the public override void OnApplyTemplate()
{
minimizedButtonContainer =
this.GetTemplateChild(partMinimizedButtonContainer)
as FrameworkElement;
base.OnApplyTemplate();
}
Although it works with any name, it is recommended that you use a name that begins with " [TemplatePart(Name = partMinimizedButtonContainer)]
public class OutlookBar : HeaderedItemsControl
{
const string partMinimizedButtonContainer = "PART_MinimizedContainer";
Note that although Skins instead of themes, and how it worksUnlike the <Style TargetType="{x:Type ButtonBase }" x:Key="buttonStyle">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ButtonBase}">
<Border Background="{TemplateBinding Background}"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Focusable="False"
x:Name="border"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{DynamicResource BorderBrush}" >
<ContentPresenter Focusable="False"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
VerticalAlignment="Center"
HorizontalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background"
Value="{DynamicResource HighlightButtonGradientBrush}"
TargetName="border"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background"
Value="{DynamicResource SelectedButtonGradientBrush}"
TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
The protected void ApplySkin()
{
string skinName;
switch (Skin)
{
case OdysseySkin.OutllookBlue: skinName = "OutlookBlueSkin"; break;
case OdysseySkin.OutlookSilver: skinName = "OutlookSilverSkin"; break;
case OdysseySkin.OutlookBlack: skinName = "OutlookBlackSkin"; break;
default: skinName = "OutlookBlueSkin"; break;
}
if (!string.IsNullOrEmpty(skinName))
{
skinName = string.Format
("pack://application:,,,/Odyssey;Component/Skins/OutlookBar/{0}.xaml",
skinName);
Uri uri = new Uri(skinName, UriKind.Absolute);
ResourceDictionary skin = new ResourceDictionary();
skin.Source = uri;
this.Resources = skin;
}
}
A skin is a <ResourceDictionary xmlns=
"xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<SolidColorBrush Color="#FFC7CBD1" x:Key="BorderBrush"/>
<SolidColorBrush Color="#FF313431" x:Key="ImageBrush"/>
<SolidColorBrush Color="#FFD8DBDF" x:Key="LightBackgroundBrush"/>
<SolidColorBrush Color="#FF000000" x:Key="ForegroundBrush"/>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,0"
x:Key="HighlightedExpanderHeaderBrush">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFDADFE6" Offset="0"/>
<GradientStop Color="White" Offset="0.5"/>
<GradientStop Color="#FFDADFE6" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"
x:Key="OutlookbarHeaderBrush">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFF0F1F2" Offset="0"/>
<GradientStop Color="#FFBDC1C8" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"
x:Key="SectionButtonGradientBrush">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFF8F8F9" Offset="0"/>
<GradientStop Color="#FFDFE2E4" Offset="0.4"/>
<GradientStop Color="#FFC7CBD1" Offset="0.4"/>
<GradientStop Color="#FFDBDEE2" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush Color="#FFFFAB3F" x:Key="SelectedButtonSolidBrush"/>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"
x:Key="SelectedButtonGradientBrush">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFFFFEE4" Offset="0"/>
<GradientStop Color="#FFFFBB6E" Offset="0.4"/>
<GradientStop Color="#FFFFAB3F" Offset="0.4"/>
<GradientStop Color="#FFFEE17A" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
<SolidColorBrush Color="#FFFFD76A" x:Key="HighlightButtonSolidBrush"/>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1"
x:Key="HighlightButtonGradientBrush">
<LinearGradientBrush.GradientStops>
<GradientStop Color="#FFFFFCDE" Offset="0"/>
<GradientStop Color="#FFFFEAAD" Offset="0.4"/>
<GradientStop Color="#FFFFD76A" Offset="0.4"/>
<GradientStop Color="#FFFFE69E" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</ResourceDictionary>
More detailsIf you're interested in more details, e.g., how the manual splitting works, or how the section buttons are separated between the maximized and minimized, you are free to look at the code to figure out how it works. I won't go into details, as it is hard to explain but easy to understand when you just see the code available here. Where can I get updates?Odyssey is an open source project available on CodePlex as source code. What comes next?The next control that I will possibly add to Odyssey is a HistorySee also: for the other articles about the
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||