7 changed files with 293 additions and 173 deletions
|
After Width: | Height: | Size: 601 B |
@ -0,0 +1,147 @@ |
|||||
|
using System; |
||||
|
using System.Windows; |
||||
|
using System.Windows.Controls; |
||||
|
using System.Windows.Input; |
||||
|
using System.Windows.Controls.Primitives; |
||||
|
|
||||
|
namespace Microsoft.Windows.Controls |
||||
|
{ |
||||
|
public class MultiLineTextEditor : ContentControl |
||||
|
{ |
||||
|
#region Members
|
||||
|
|
||||
|
TextBox _textBox; |
||||
|
Thumb _resizeThumb; |
||||
|
|
||||
|
#endregion //Members
|
||||
|
|
||||
|
#region Properties
|
||||
|
|
||||
|
#region IsOpen
|
||||
|
|
||||
|
public static readonly DependencyProperty IsOpenProperty = DependencyProperty.Register("IsOpen", typeof(bool), typeof(MultiLineTextEditor), new UIPropertyMetadata(false, OnIsOpenChanged)); |
||||
|
public bool IsOpen |
||||
|
{ |
||||
|
get { return (bool)GetValue(IsOpenProperty); } |
||||
|
set { SetValue(IsOpenProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnIsOpenChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MultiLineTextEditor multiLineTextEditor = o as MultiLineTextEditor; |
||||
|
if (multiLineTextEditor != null) |
||||
|
multiLineTextEditor.OnIsOpenChanged((bool)e.OldValue, (bool)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnIsOpenChanged(bool oldValue, bool newValue) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endregion //IsOpen
|
||||
|
|
||||
|
#region Text
|
||||
|
|
||||
|
public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(MultiLineTextEditor), new FrameworkPropertyMetadata(String.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnTextChanged)); |
||||
|
public string Text |
||||
|
{ |
||||
|
get { return (string)GetValue(TextProperty); } |
||||
|
set { SetValue(TextProperty, value); } |
||||
|
} |
||||
|
|
||||
|
private static void OnTextChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) |
||||
|
{ |
||||
|
MultiLineTextEditor textEditor = o as MultiLineTextEditor; |
||||
|
if (textEditor != null) |
||||
|
textEditor.OnTextChanged((string)e.OldValue, (string)e.NewValue); |
||||
|
} |
||||
|
|
||||
|
protected virtual void OnTextChanged(string oldValue, string newValue) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
#endregion //Text
|
||||
|
|
||||
|
#endregion //Properties
|
||||
|
|
||||
|
#region Constructors
|
||||
|
|
||||
|
static MultiLineTextEditor() |
||||
|
{ |
||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(MultiLineTextEditor), new FrameworkPropertyMetadata(typeof(MultiLineTextEditor))); |
||||
|
} |
||||
|
|
||||
|
public MultiLineTextEditor() |
||||
|
{ |
||||
|
Keyboard.AddKeyDownHandler(this, OnKeyDown); |
||||
|
Mouse.AddPreviewMouseDownOutsideCapturedElementHandler(this, OnMouseDownOutsideCapturedElement); |
||||
|
} |
||||
|
|
||||
|
#endregion //Constructors
|
||||
|
|
||||
|
#region Bass Class Overrides
|
||||
|
|
||||
|
public override void OnApplyTemplate() |
||||
|
{ |
||||
|
base.OnApplyTemplate(); |
||||
|
|
||||
|
_textBox = (TextBox)GetTemplateChild("PART_TextBox"); |
||||
|
|
||||
|
if (_resizeThumb != null) |
||||
|
_resizeThumb.DragDelta -= ResizeThumb_DragDelta; |
||||
|
_resizeThumb = (Thumb)GetTemplateChild("PART_ResizeThumb"); |
||||
|
|
||||
|
if (_resizeThumb != null) |
||||
|
_resizeThumb.DragDelta += ResizeThumb_DragDelta; |
||||
|
|
||||
|
} |
||||
|
|
||||
|
void ResizeThumb_DragDelta(object sender, DragDeltaEventArgs e) |
||||
|
{ |
||||
|
double yadjust = this._textBox.Height + e.VerticalChange; |
||||
|
double xadjust = this._textBox.Width + e.HorizontalChange; |
||||
|
|
||||
|
if ((xadjust >= 0) && (yadjust >= 0)) |
||||
|
{ |
||||
|
this._textBox.Width = xadjust; |
||||
|
this._textBox.Height = yadjust; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endregion //Bass Class Overrides
|
||||
|
|
||||
|
#region Event Handlers
|
||||
|
|
||||
|
private void OnKeyDown(object sender, KeyEventArgs e) |
||||
|
{ |
||||
|
switch (e.Key) |
||||
|
{ |
||||
|
case Key.Escape: |
||||
|
case Key.Tab: |
||||
|
{ |
||||
|
CloseEditor(); |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private void OnMouseDownOutsideCapturedElement(object sender, MouseButtonEventArgs e) |
||||
|
{ |
||||
|
CloseEditor(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Event Handlers
|
||||
|
|
||||
|
#region Methods
|
||||
|
|
||||
|
private void CloseEditor() |
||||
|
{ |
||||
|
if (IsOpen) |
||||
|
IsOpen = false; |
||||
|
ReleaseMouseCapture(); |
||||
|
} |
||||
|
|
||||
|
#endregion //Methods
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,125 @@ |
|||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
|
xmlns:local="clr-namespace:Microsoft.Windows.Controls" |
||||
|
xmlns:chrome="clr-namespace:Microsoft.Windows.Controls.Chromes" |
||||
|
xmlns:coreConverters="clr-namespace:Microsoft.Windows.Controls.Core.Converters"> |
||||
|
|
||||
|
<coreConverters:InverseBoolConverter x:Key="InverseBoolConverter" /> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="PopupDarkBorderBrush" EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFA3AEB9" Offset="0"/> |
||||
|
<GradientStop Color="#FF8399A9" Offset="0.375"/> |
||||
|
<GradientStop Color="#FF718597" Offset="0.375"/> |
||||
|
<GradientStop Color="#FF617584" Offset="1"/> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<LinearGradientBrush x:Key="PopupBackgroundBrush" StartPoint="0,0" EndPoint="0,1"> |
||||
|
<LinearGradientBrush.GradientStops> |
||||
|
<GradientStopCollection> |
||||
|
<GradientStop Offset="0" Color="#FFffffff"/> |
||||
|
<GradientStop Offset="1" Color="#FFE8EBED"/> |
||||
|
</GradientStopCollection> |
||||
|
</LinearGradientBrush.GradientStops> |
||||
|
</LinearGradientBrush> |
||||
|
|
||||
|
<Style x:Key="ToggleButtonStyle" TargetType="ToggleButton"> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="ToggleButton"> |
||||
|
<Grid SnapsToDevicePixels="True"> |
||||
|
|
||||
|
<Grid> |
||||
|
<Grid.ColumnDefinitions> |
||||
|
<ColumnDefinition Width="*"/> |
||||
|
<ColumnDefinition Width="Auto"/> |
||||
|
</Grid.ColumnDefinitions> |
||||
|
|
||||
|
<Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="True"> |
||||
|
<ContentPresenter Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" |
||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"/> |
||||
|
</Border> |
||||
|
|
||||
|
<chrome:ButtonChrome x:Name="ToggleButtonChrome" Grid.Column="1" |
||||
|
CornerRadius="0,2.75,2.75,0" |
||||
|
RenderChecked="{Binding IsOpen, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:MultiLineTextEditor}}" |
||||
|
RenderEnabled="{Binding IsEnabled, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=local:MultiLineTextEditor}}" |
||||
|
RenderMouseOver="{TemplateBinding IsMouseOver}" |
||||
|
RenderPressed="{TemplateBinding IsPressed}" > |
||||
|
|
||||
|
<Grid x:Name="arrowGlyph" IsHitTestVisible="False" Grid.Column="1" Margin="5"> |
||||
|
<Path Width="7" Height="4" Data="M 0,1 C0,1 0,0 0,0 0,0 3,0 3,0 3,0 3,1 3,1 3,1 4,1 4,1 4,1 4,0 4,0 4,0 7,0 7,0 7,0 7,1 7,1 7,1 6,1 6,1 6,1 6,2 6,2 6,2 5,2 5,2 5,2 5,3 5,3 5,3 4,3 4,3 4,3 4,4 4,4 4,4 3,4 3,4 3,4 3,3 3,3 3,3 2,3 2,3 2,3 2,2 2,2 2,2 1,2 1,2 1,2 1,1 1,1 1,1 0,1 0,1 z" Fill="#FF000000"/> |
||||
|
</Grid> |
||||
|
</chrome:ButtonChrome> |
||||
|
</Grid> |
||||
|
|
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
<Style TargetType="{x:Type local:MultiLineTextEditor}"> |
||||
|
<Setter Property="Background" Value="White"/> |
||||
|
<Setter Property="BorderBrush"> |
||||
|
<Setter.Value> |
||||
|
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0"> |
||||
|
<GradientStop Color="#FFA3AEB9" Offset="0" /> |
||||
|
<GradientStop Color="#FF8399A9" Offset="0.375" /> |
||||
|
<GradientStop Color="#FF718597" Offset="0.375" /> |
||||
|
<GradientStop Color="#FF617584" Offset="1" /> |
||||
|
</LinearGradientBrush> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
<Setter Property="BorderThickness" Value="1,1,0,1" /> |
||||
|
<Setter Property="Content"> |
||||
|
<Setter.Value> |
||||
|
<Image Height="16" Width="18" Source="/WPFToolkit.Extended;component/CollectionEditors/Images/Notes16.png" /> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
<Setter Property="Focusable" Value="False" /> |
||||
|
<Setter Property="Padding" Value="2,0,0,0" /> |
||||
|
<Setter Property="HorizontalContentAlignment" Value="Center" /> |
||||
|
<Setter Property="VerticalContentAlignment" Value="Center" /> |
||||
|
<Setter Property="Template"> |
||||
|
<Setter.Value> |
||||
|
<ControlTemplate TargetType="{x:Type local:MultiLineTextEditor}"> |
||||
|
<Grid x:Name="Root"> |
||||
|
<ToggleButton x:Name="PART_DropDownButton" Grid.Column="1" IsTabStop="True" MinHeight="22" SnapsToDevicePixels="True" |
||||
|
Background="{TemplateBinding Background}" |
||||
|
BorderBrush="{TemplateBinding BorderBrush}" |
||||
|
BorderThickness="{TemplateBinding BorderThickness}" |
||||
|
Padding="{TemplateBinding Padding}" |
||||
|
Content="{TemplateBinding Content}" |
||||
|
ContentTemplate="{TemplateBinding ContentTemplate}" ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}" |
||||
|
IsChecked="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Style="{StaticResource ToggleButtonStyle}" |
||||
|
IsHitTestVisible="{Binding IsOpen, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource InverseBoolConverter}}" |
||||
|
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"/> |
||||
|
<Popup IsOpen="{Binding IsChecked, ElementName=PART_DropDownButton}" StaysOpen="False" |
||||
|
Placement="Bottom" SnapsToDevicePixels="True" AllowsTransparency="True" Focusable="False" PopupAnimation="Slide"> |
||||
|
<Border BorderThickness="1" Background="{StaticResource PopupBackgroundBrush}" BorderBrush="{StaticResource PopupDarkBorderBrush}"> |
||||
|
<Grid> |
||||
|
<TextBox x:Name="PART_TextBox" AcceptsReturn="true" TextWrapping="NoWrap" Padding="{TemplateBinding Padding}" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" |
||||
|
Width="200" Height="150" |
||||
|
Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}}" |
||||
|
Margin="3"> |
||||
|
</TextBox> |
||||
|
<Thumb x:Name="PART_ResizeThumb" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE"> |
||||
|
<Thumb.Template> |
||||
|
<ControlTemplate TargetType="{x:Type Thumb}"> |
||||
|
<Grid Background="Transparent"> |
||||
|
<Path Data="M0.5,6.5 L6.5,0.5 M6.5,3.5 L3.5,6.5" Stroke="Black" StrokeThickness="1" /> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Thumb.Template> |
||||
|
</Thumb> |
||||
|
</Grid> |
||||
|
</Border> |
||||
|
</Popup> |
||||
|
</Grid> |
||||
|
</ControlTemplate> |
||||
|
</Setter.Value> |
||||
|
</Setter> |
||||
|
</Style> |
||||
|
|
||||
|
</ResourceDictionary> |
||||
Loading…
Reference in new issue