|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace System.Activities.Core.Presentation
{
using System;
using System.Activities.Presentation;
using System.Windows;
using System.Windows.Automation;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Threading;
partial class CaseKeyBox : UserControl, ICaseKeyBoxView
{
public static readonly DependencyProperty DisplayHintTextProperty =
DependencyProperty.Register("DisplayHintText", typeof(bool), typeof(CaseKeyBox));
public static readonly DependencyProperty LabelTextProperty =
DependencyProperty.Register("LabelText", typeof(string), typeof(CaseKeyBox), new UIPropertyMetadata(string.Empty));
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(object), typeof(CaseKeyBox), new PropertyMetadata(OnValueChanged));
public static readonly DependencyProperty ValueTypeProperty =
DependencyProperty.Register("ValueType", typeof(Type), typeof(CaseKeyBox), new PropertyMetadata(OnValueTypeChanged));
public static readonly DependencyProperty EditorAutomationNameProperty =
DependencyProperty.Register("EditorAutomationName", typeof(string), typeof(CaseKeyBox));
public static readonly DependencyProperty ComboBoxAutomationNameProperty =
DependencyProperty.Register("ComboBoxAutomationName", typeof(string), typeof(CaseKeyBox));
public static RoutedEvent ValueCommittedEvent =
EventManager.RegisterRoutedEvent("ValueCommitted", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CaseKeyBox));
public static RoutedEvent EditCancelledEvent =
EventManager.RegisterRoutedEvent("EditCancelled", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(CaseKeyBox));
public static readonly DependencyProperty CaseKeyValidationCallbackProperty =
DependencyProperty.Register("CaseKeyValidationCallback", typeof(CaseKeyValidationCallbackDelegate), typeof(CaseKeyBox));
public static readonly DependencyProperty ErrorCallbackProperty =
DependencyProperty.Register("ErrorCallback", typeof(Action<CaseKeyBox>), typeof(CaseKeyBox));
public static readonly DependencyProperty CommitExplicitlyProperty =
DependencyProperty.Register("CommitExplicitly", typeof(bool), typeof(CaseKeyBox), new PropertyMetadata(false));
Control visibleBox;
public CaseKeyBox()
{
this.ViewModel = new CaseKeyBoxViewModel(this);
InitializeComponent();
}
public event RoutedEventHandler ValueCommitted
{
add { AddHandler(ValueCommittedEvent, value); }
remove { RemoveHandler(ValueCommittedEvent, value); }
}
public virtual void OnValueCommitted()
{
RoutedEventArgs args = new RoutedEventArgs();
args.RoutedEvent = ValueCommittedEvent;
RaiseEvent(args);
}
public event RoutedEventHandler EditCancelled
{
add { AddHandler(EditCancelledEvent, value); }
remove { RemoveHandler(EditCancelledEvent, value); }
}
public virtual void OnEditCancelled()
{
RoutedEventArgs args = new RoutedEventArgs();
args.RoutedEvent = EditCancelledEvent;
RaiseEvent(args);
}
public CaseKeyValidationCallbackDelegate CaseKeyValidationCallback
{
get { return (CaseKeyValidationCallbackDelegate)GetValue(CaseKeyValidationCallbackProperty); }
set { SetValue(CaseKeyValidationCallbackProperty, value); }
}
public Action<CaseKeyBox> ErrorCallback
{
get { return (Action<CaseKeyBox>)GetValue(ErrorCallbackProperty); }
set { SetValue(ErrorCallbackProperty, value); }
}
public bool CommitExplicitly
{
get { return (bool)GetValue(CommitExplicitlyProperty); }
set { SetValue(CommitExplicitlyProperty, value); }
}
public string LabelText
{
get { return (string)GetValue(LabelTextProperty); }
set { SetValue(LabelTextProperty, value); }
}
void DisableKeyboardLostFocus()
{
if (this.visibleBox != null)
{
this.visibleBox.LostKeyboardFocus -= OnLostKeyboardFocus;
}
}
void EnableKeyboardLostFocus()
{
if (!this.CommitExplicitly)
{
if (this.visibleBox != null)
{
this.visibleBox.LostKeyboardFocus += OnLostKeyboardFocus;
}
}
}
void ReportError(string errorMessage)
{
// Invoking error message box will cause LostFocus of the control.
// Thus we need to disable LostFocus first and then add the handlers back.
DisableKeyboardLostFocus();
ErrorReporting.ShowErrorMessage(errorMessage);
this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
{
if (this.ErrorCallback != null)
{
this.ErrorCallback(this);
this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
{
RegainFocus();
EnableKeyboardLostFocus();
}));
}
else
{
RegainFocus();
EnableKeyboardLostFocus();
}
}));
}
void OnBoxMouseUp(object sender, MouseButtonEventArgs e)
{
// disable the context menu for textbox and combobox
if (e.ChangedButton == MouseButton.Right && e.RightButton == MouseButtonState.Released)
{
e.Handled = true;
}
}
#region ICaseKeyBoxView Implementation
public bool DisplayHintText
{
get { return (bool)GetValue(DisplayHintTextProperty); }
set { SetValue(DisplayHintTextProperty, value); }
}
public object Value
{
get { return (object)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public Type ValueType
{
get { return (Type)GetValue(ValueTypeProperty); }
set { SetValue(ValueTypeProperty, value); }
}
public string ComboBoxAutomationName
{
get { return (string)GetValue(ComboBoxAutomationNameProperty); }
set { SetValue(ComboBoxAutomationNameProperty, value); }
}
public string EditorAutomationName
{
get { return (string)GetValue(EditorAutomationNameProperty); }
set { SetValue(EditorAutomationNameProperty, value); }
}
public void RegainFocus()
{
if (this.visibleBox != null)
{
Keyboard.Focus((IInputElement)this.visibleBox);
}
}
#endregion
#region Delegating Event Handlers
public CaseKeyBoxViewModel ViewModel { get; set; }
static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
{
((CaseKeyBox)sender).ViewModel.OnValueChanged();
}
static void OnValueTypeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs eventArgs)
{
((CaseKeyBox)sender).ViewModel.OnValueTypeChanged();
}
void OnLabelGotFocus(object sender, RoutedEventArgs e)
{
this.ViewModel.OnLabelGotFocus();
e.Handled = true;
}
void OnLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
e.Handled = true;
if (ComboBoxHelper.ShouldFilterUnnecessaryComboBoxEvent(sender as ComboBox))
{
return;
}
CommitChanges();
}
public bool CommitChanges()
{
UpdateSource(this.visibleBox);
if (this.CommitExplicitly || this.ViewModel.TextHasBeenChanged())
{
string reason = null;
if (!this.ViewModel.CanResolveInputText(out reason))
{
ReportError(reason);
return false;
}
else
{
return this.ViewModel.OnLostFocus();
}
}
else
{
CancelChanges();
return false;
}
}
public void CancelChanges()
{
DisableKeyboardLostFocus();
this.ViewModel.OnEscapePressed(); // simulate cancel
}
void OnBoxLoaded(object sender, RoutedEventArgs e)
{
UIElement box = (UIElement)sender;
ComboBox comboBox = box as ComboBox;
if (comboBox != null)
{
if (!LocalAppContextSwitches.UseLegacyAccessibilityFeatures)
{
if (!string.IsNullOrEmpty(ComboBoxAutomationName))
{
comboBox.SetValue(AutomationProperties.NameProperty, ComboBoxAutomationName);
}
if (comboBox.IsEditable && comboBox.Template != null)
{
var comboBoxTextBox = comboBox.Template.FindName("PART_EditableTextBox", comboBox) as TextBox;
if (comboBoxTextBox != null && !string.IsNullOrEmpty(EditorAutomationName))
{
comboBoxTextBox.SetValue(AutomationProperties.NameProperty, EditorAutomationName);
}
}
}
if (comboBox.IsVisible)
{
ComboBoxHelper.SynchronizeComboBoxSelection(comboBox, this.ViewModel.Text);
}
}
if (!LocalAppContextSwitches.UseLegacyAccessibilityFeatures)
{
TextBox textBox = box as TextBox;
if (textBox != null && !string.IsNullOrEmpty(EditorAutomationName))
{
textBox.SetValue(AutomationProperties.NameProperty, EditorAutomationName);
}
}
if (box.IsVisible)
{
box.Focus();
}
Control control = sender as Control;
if (control != null && control.Visibility == Visibility.Visible)
{
this.visibleBox = control;
EnableKeyboardLostFocus();
}
this.ViewModel.SaveOldText();
}
void OnBoxUnloaded(object sender, RoutedEventArgs e)
{
if (this.visibleBox != null)
{
DisableKeyboardLostFocus();
this.visibleBox = null;
}
}
void OnBoxKeyDown(object sender, KeyEventArgs e)
{
if (!CommitExplicitly)
{
if (e.Key == Key.Escape)
{
e.Handled = true;
CancelChanges();
}
else if (e.Key == Key.Enter)
{
e.Handled = true;
CommitChanges();
}
}
}
void UpdateSource(object sender)
{
if (sender is TextBox)
{
BindingExpression binding = ((TextBox)sender).GetBindingExpression(TextBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
else if (sender is ComboBox)
{
BindingExpression binding = ((ComboBox)sender).GetBindingExpression(ComboBox.TextProperty);
if (binding != null)
{
binding.UpdateSource();
}
}
}
#endregion
public void ResetText()
{
this.ViewModel.ResetText();
}
}
}
|