mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-24 20:57:19 -08:00
Auto scroll when text changed or selection changed in a TextBox
This commit is contained in:
parent
4cb2568385
commit
bd96a9709f
5 changed files with 360 additions and 279 deletions
|
@ -1,5 +1,6 @@
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
|
||||||
namespace SourceGit.Helpers {
|
namespace SourceGit.Helpers {
|
||||||
|
@ -9,6 +10,15 @@ namespace SourceGit.Helpers {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class TextBoxHelper {
|
public static class TextBoxHelper {
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Auto scroll on text changed.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty AutoScrollProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"AutoScroll",
|
||||||
|
typeof(bool),
|
||||||
|
typeof(TextBoxHelper),
|
||||||
|
new PropertyMetadata(false, OnAutoScrollChanged));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Placeholder property
|
/// Placeholder property
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -36,6 +46,39 @@ namespace SourceGit.Helpers {
|
||||||
typeof(TextBoxHelper),
|
typeof(TextBoxHelper),
|
||||||
new PropertyMetadata(Brushes.Transparent));
|
new PropertyMetadata(Brushes.Transparent));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Setter for AutoScrollProperty
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="element"></param>
|
||||||
|
/// <param name="enabled"></param>
|
||||||
|
public static void SetAutoScroll(UIElement element, bool enabled) {
|
||||||
|
element.SetValue(AutoScrollProperty, enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Getter for AutoScrollProperty
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="element"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static bool GetAutoScroll(UIElement element) {
|
||||||
|
return (bool)element.GetValue(AutoScrollProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Triggered when AutoScroll property changed.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="d"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
public static void OnAutoScrollChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
|
||||||
|
var textBox = d as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
textBox.SelectionChanged -= UpdateScrollOnSelectionChanged;
|
||||||
|
if ((bool)e.NewValue == true) {
|
||||||
|
textBox.SelectionChanged += UpdateScrollOnSelectionChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Triggered when placeholder changed.
|
/// Triggered when placeholder changed.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -122,8 +165,8 @@ namespace SourceGit.Helpers {
|
||||||
|
|
||||||
textBox.SetValue(PlaceholderBrushProperty, brush);
|
textBox.SetValue(PlaceholderBrushProperty, brush);
|
||||||
textBox.Background = brush;
|
textBox.Background = brush;
|
||||||
textBox.TextChanged += OnTextChanged;
|
textBox.TextChanged += UpdatePlaceholder;
|
||||||
OnTextChanged(textBox, null);
|
UpdatePlaceholder(textBox, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -131,7 +174,7 @@ namespace SourceGit.Helpers {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="sender"></param>
|
/// <param name="sender"></param>
|
||||||
/// <param name="e"></param>
|
/// <param name="e"></param>
|
||||||
private static void OnTextChanged(object sender, RoutedEventArgs e) {
|
private static void UpdatePlaceholder(object sender, RoutedEventArgs e) {
|
||||||
var textBox = sender as TextBox;
|
var textBox = sender as TextBox;
|
||||||
if (string.IsNullOrEmpty(textBox.Text)) {
|
if (string.IsNullOrEmpty(textBox.Text)) {
|
||||||
textBox.Background = textBox.GetValue(PlaceholderBrushProperty) as Brush;
|
textBox.Background = textBox.GetValue(PlaceholderBrushProperty) as Brush;
|
||||||
|
@ -139,5 +182,44 @@ namespace SourceGit.Helpers {
|
||||||
textBox.Background = Brushes.Transparent;
|
textBox.Background = Brushes.Transparent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sender"></param>
|
||||||
|
/// <param name="e"></param>
|
||||||
|
private static void UpdateScrollOnSelectionChanged(object sender, RoutedEventArgs e) {
|
||||||
|
var textBox = sender as TextBox;
|
||||||
|
if (textBox != null && textBox.IsFocused) {
|
||||||
|
if (Mouse.LeftButton == MouseButtonState.Pressed && textBox.SelectionLength > 0) {
|
||||||
|
var p = Mouse.GetPosition(textBox);
|
||||||
|
if (p.X <= 8) {
|
||||||
|
textBox.LineLeft();
|
||||||
|
} else if (p.X >= textBox.ActualWidth - 8) {
|
||||||
|
textBox.LineRight();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p.Y <= 8) {
|
||||||
|
textBox.LineUp();
|
||||||
|
} else if (p.Y >= textBox.ActualHeight - 8) {
|
||||||
|
textBox.LineDown();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var rect = textBox.GetRectFromCharacterIndex(textBox.CaretIndex);
|
||||||
|
if (rect.Left <= 0) {
|
||||||
|
textBox.ScrollToHorizontalOffset(textBox.HorizontalOffset + rect.Left);
|
||||||
|
} else if (rect.Right >= textBox.ActualWidth) {
|
||||||
|
textBox.ScrollToHorizontalOffset(textBox.HorizontalOffset + rect.Right);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rect.Top <= 0) {
|
||||||
|
textBox.ScrollToVerticalOffset(textBox.VerticalOffset + rect.Top);
|
||||||
|
} else if (rect.Bottom >= textBox.ActualHeight) {
|
||||||
|
textBox.ScrollToVerticalOffset(textBox.VerticalOffset + rect.Bottom);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:helpers="clr-namespace:SourceGit.Helpers">
|
||||||
|
|
||||||
<!-- 错误Tooltip -->
|
<!-- 错误Tooltip -->
|
||||||
<ControlTemplate x:Key="Template.Validation.Tooltip" TargetType="{x:Type ToolTip}">
|
<ControlTemplate x:Key="Template.Validation.Tooltip" TargetType="{x:Type ToolTip}">
|
||||||
<Border x:Name="Root" Margin="5,0,0,0" Opacity="0" Padding="0,0,20,20" RenderTransformOrigin="0,0">
|
<Border x:Name="Root" Margin="5,0,0,0" Opacity="0" Padding="0,0,20,20" RenderTransformOrigin="0,0">
|
||||||
|
@ -81,6 +83,7 @@
|
||||||
<Setter Property="Background" Value="Transparent"/>
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource Brush.Border1}"/>
|
<Setter Property="BorderBrush" Value="{DynamicResource Brush.Border1}"/>
|
||||||
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource Template.Validation.Error}"/>
|
<Setter Property="Validation.ErrorTemplate" Value="{StaticResource Template.Validation.Error}"/>
|
||||||
|
<Setter Property="helpers:TextBoxHelper.AutoScroll" Value="True"/>
|
||||||
|
|
||||||
<Setter Property="Template">
|
<Setter Property="Template">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
|
@ -93,9 +96,10 @@
|
||||||
<ScrollViewer x:Name="PART_ContentHost"
|
<ScrollViewer x:Name="PART_ContentHost"
|
||||||
Margin="{TemplateBinding Padding}"
|
Margin="{TemplateBinding Padding}"
|
||||||
VerticalAlignment="Center"
|
VerticalAlignment="Center"
|
||||||
Background="{x:Null}"
|
Background="Transparent"
|
||||||
BorderThickness="0"
|
BorderThickness="0"
|
||||||
IsTabStop="False"
|
IsTabStop="False"
|
||||||
|
CanContentScroll="False"
|
||||||
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net461</TargetFramework>
|
<TargetFramework>net46</TargetFramework>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<UseWPF>true</UseWPF>
|
<UseWPF>true</UseWPF>
|
||||||
<UseWindowsForms>true</UseWindowsForms>
|
<UseWindowsForms>true</UseWindowsForms>
|
||||||
|
|
|
@ -343,8 +343,7 @@
|
||||||
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
|
||||||
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
ScrollViewer.VerticalScrollBarVisibility="Auto"
|
||||||
helpers:TextBoxHelper.Placeholder="Enter commit message"
|
helpers:TextBoxHelper.Placeholder="Enter commit message"
|
||||||
helpers:TextBoxHelper.PlaceholderBaseline="Top"
|
helpers:TextBoxHelper.PlaceholderBaseline="Top">
|
||||||
TextChanged="CommitMessageChanged">
|
|
||||||
<TextBox.Text>
|
<TextBox.Text>
|
||||||
<Binding ElementName="me" Path="CommitMessage" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
|
<Binding ElementName="me" Path="CommitMessage" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
|
||||||
<Binding.ValidationRules>
|
<Binding.ValidationRules>
|
||||||
|
|
|
@ -729,10 +729,6 @@ namespace SourceGit.UI {
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CommitMessageChanged(object sender, TextChangedEventArgs e) {
|
|
||||||
(sender as TextBox).ScrollToEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void StartAmend(object sender, RoutedEventArgs e) {
|
private void StartAmend(object sender, RoutedEventArgs e) {
|
||||||
var commits = Repo.Commits("-n 1");
|
var commits = Repo.Commits("-n 1");
|
||||||
if (commits.Count == 0) {
|
if (commits.Count == 0) {
|
||||||
|
|
Loading…
Reference in a new issue