Browse Source

Merge branch 'auto-complete-box-control' of https://github.com/sdoroff/Avalonia into auto-complete-box-control

pull/1427/head
sdoroff 9 years ago
parent
commit
54725ca802
  1. 232
      src/Avalonia.Controls/AutoCompleteBox.cs

232
src/Avalonia.Controls/AutoCompleteBox.cs

@ -248,7 +248,7 @@ namespace Avalonia.Controls
/// Specifies the name of the Popup TemplatePart. /// Specifies the name of the Popup TemplatePart.
/// </summary> /// </summary>
private const string ElementPopup = "PART_Popup"; private const string ElementPopup = "PART_Popup";
/// <summary> /// <summary>
/// The name for the text box part. /// The name for the text box part.
/// </summary> /// </summary>
@ -262,37 +262,37 @@ namespace Avalonia.Controls
private List<object> _items; private List<object> _items;
/// <summary> /// <summary>
/// Gets or sets the observable collection that contains references to /// Gets or sets the observable collection that contains references to
/// all of the items in the generated view of data that is provided to /// all of the items in the generated view of data that is provided to
/// the selection-style control adapter. /// the selection-style control adapter.
/// </summary> /// </summary>
private AvaloniaList<object> _view; private AvaloniaList<object> _view;
/// <summary> /// <summary>
/// Gets or sets a value to ignore a number of pending change handlers. /// Gets or sets a value to ignore a number of pending change handlers.
/// The value is decremented after each use. This is used to reset the /// The value is decremented after each use. This is used to reset the
/// value of properties without performing any of the actions in their /// value of properties without performing any of the actions in their
/// change handlers. /// change handlers.
/// </summary> /// </summary>
/// <remarks>The int is important as a value because the TextBox /// <remarks>The int is important as a value because the TextBox
/// TextChanged event does not immediately fire, and this will allow for /// TextChanged event does not immediately fire, and this will allow for
/// nested property changes to be ignored.</remarks> /// nested property changes to be ignored.</remarks>
private int _ignoreTextPropertyChange; private int _ignoreTextPropertyChange;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether to ignore calling a pending /// Gets or sets a value indicating whether to ignore calling a pending
/// change handlers. /// change handlers.
/// </summary> /// </summary>
private bool _ignorePropertyChange; private bool _ignorePropertyChange;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether to ignore the selection /// Gets or sets a value indicating whether to ignore the selection
/// changed event. /// changed event.
/// </summary> /// </summary>
private bool _ignoreTextSelectionChange; private bool _ignoreTextSelectionChange;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether to skip the text update /// Gets or sets a value indicating whether to skip the text update
/// processing when the selected item is updated. /// processing when the selected item is updated.
/// </summary> /// </summary>
private bool _skipSelectedItemTextUpdate; private bool _skipSelectedItemTextUpdate;
@ -303,7 +303,7 @@ namespace Avalonia.Controls
private int _textSelectionStart; private int _textSelectionStart;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether the user initiated the /// Gets or sets a value indicating whether the user initiated the
/// current populate call. /// current populate call.
/// </summary> /// </summary>
private bool _userCalledPopulate; private bool _userCalledPopulate;
@ -314,15 +314,15 @@ namespace Avalonia.Controls
private bool _popupHasOpened; private bool _popupHasOpened;
/// <summary> /// <summary>
/// Gets or sets the DispatcherTimer used for the MinimumPopulateDelay /// Gets or sets the DispatcherTimer used for the MinimumPopulateDelay
/// condition for auto completion. /// condition for auto completion.
/// </summary> /// </summary>
private DispatcherTimer _delayTimer; private DispatcherTimer _delayTimer;
/// <summary> /// <summary>
/// Gets or sets a value indicating whether a read-only dependency /// Gets or sets a value indicating whether a read-only dependency
/// property change handler should allow the value to be set. This is /// property change handler should allow the value to be set. This is
/// used to ensure that read-only properties cannot be changed via /// used to ensure that read-only properties cannot be changed via
/// SetValue, etc. /// SetValue, etc.
/// </summary> /// </summary>
private bool _allowWrite; private bool _allowWrite;
@ -394,7 +394,7 @@ namespace Avalonia.Controls
/// dependency property.</value> /// dependency property.</value>
public static readonly StyledProperty<TimeSpan> MinimumPopulateDelayProperty = public static readonly StyledProperty<TimeSpan> MinimumPopulateDelayProperty =
AvaloniaProperty.Register<AutoCompleteBox, TimeSpan>( AvaloniaProperty.Register<AutoCompleteBox, TimeSpan>(
nameof(MinimumPopulateDelay), nameof(MinimumPopulateDelay),
TimeSpan.Zero, TimeSpan.Zero,
validate: ValidateMinimumPopulateDelay); validate: ValidateMinimumPopulateDelay);
@ -408,7 +408,7 @@ namespace Avalonia.Controls
/// dependency property.</value> /// dependency property.</value>
public static readonly StyledProperty<double> MaxDropDownHeightProperty = public static readonly StyledProperty<double> MaxDropDownHeightProperty =
AvaloniaProperty.Register<AutoCompleteBox, double>( AvaloniaProperty.Register<AutoCompleteBox, double>(
nameof(MaxDropDownHeight), nameof(MaxDropDownHeight),
double.PositiveInfinity, double.PositiveInfinity,
validate: ValidateMaxDropDownHeight); validate: ValidateMaxDropDownHeight);
@ -576,7 +576,7 @@ namespace Avalonia.Controls
return value; return value;
} }
private static bool IsValidFilterMode(AutoCompleteFilterMode mode) private static bool IsValidFilterMode(AutoCompleteFilterMode mode)
{ {
switch (mode) switch (mode)
@ -621,15 +621,15 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// MinimumPopulateDelayProperty property changed handler. Any current /// MinimumPopulateDelayProperty property changed handler. Any current
/// dispatcher timer will be stopped. The timer will not be restarted /// dispatcher timer will be stopped. The timer will not be restarted
/// until the next TextUpdate call by the user. /// until the next TextUpdate call by the user.
/// </summary> /// </summary>
/// <param name="e">Event arguments.</param> /// <param name="e">Event arguments.</param>
private void OnMinimumPopulateDelayChanged(AvaloniaPropertyChangedEventArgs e) private void OnMinimumPopulateDelayChanged(AvaloniaPropertyChangedEventArgs e)
{ {
var newValue = (TimeSpan)e.NewValue; var newValue = (TimeSpan)e.NewValue;
// Stop any existing timer // Stop any existing timer
if (_delayTimer != null) if (_delayTimer != null)
{ {
@ -882,12 +882,12 @@ namespace Avalonia.Controls
/// <value>The <see cref="T:Avalonia.DataTemplate" /> used to /// <value>The <see cref="T:Avalonia.DataTemplate" /> used to
/// display each item in the drop-down. The default is null.</value> /// display each item in the drop-down. The default is null.</value>
/// <remarks> /// <remarks>
/// You use the ItemTemplate property to specify the visualization /// You use the ItemTemplate property to specify the visualization
/// of the data objects in the drop-down portion of the AutoCompleteBox /// of the data objects in the drop-down portion of the AutoCompleteBox
/// control. If your AutoCompleteBox is bound to a collection and you /// control. If your AutoCompleteBox is bound to a collection and you
/// do not provide specific display instructions by using a /// do not provide specific display instructions by using a
/// DataTemplate, the resulting UI of each item is a string /// DataTemplate, the resulting UI of each item is a string
/// representation of each object in the underlying collection. /// representation of each object in the underlying collection.
/// </remarks> /// </remarks>
public IDataTemplate ItemTemplate public IDataTemplate ItemTemplate
{ {
@ -960,7 +960,7 @@ namespace Avalonia.Controls
} }
} }
} }
/// <summary> /// <summary>
/// Gets or sets the MemberSelector that is used to get values for /// Gets or sets the MemberSelector that is used to get values for
/// display in the text portion of the /// display in the text portion of the
@ -974,15 +974,15 @@ namespace Avalonia.Controls
get { return _valueMemberSelector; } get { return _valueMemberSelector; }
set { SetAndRaise(ValueMemberSelectorProperty, ref _valueMemberSelector, value); } set { SetAndRaise(ValueMemberSelectorProperty, ref _valueMemberSelector, value); }
} }
/// <summary> /// <summary>
/// Gets or sets the selected item in the drop-down. /// Gets or sets the selected item in the drop-down.
/// </summary> /// </summary>
/// <value>The selected item in the drop-down.</value> /// <value>The selected item in the drop-down.</value>
/// <remarks> /// <remarks>
/// If the IsTextCompletionEnabled property is true and text typed by /// If the IsTextCompletionEnabled property is true and text typed by
/// the user matches an item in the ItemsSource collection, which is /// the user matches an item in the ItemsSource collection, which is
/// then displayed in the text box, the SelectedItem property will be /// then displayed in the text box, the SelectedItem property will be
/// a null reference. /// a null reference.
/// </remarks> /// </remarks>
public object SelectedItem public object SelectedItem
@ -1012,8 +1012,8 @@ namespace Avalonia.Controls
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" /> /// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" />
/// item collection.</value> /// item collection.</value>
/// <remarks> /// <remarks>
/// The SearchText value is typically the same as the /// The SearchText value is typically the same as the
/// Text property, but is set after the TextChanged event occurs /// Text property, but is set after the TextChanged event occurs
/// and before the Populating event. /// and before the Populating event.
/// </remarks> /// </remarks>
public string SearchText public string SearchText
@ -1047,10 +1047,10 @@ namespace Avalonia.Controls
/// not a valid /// not a valid
/// <see cref="T:Avalonia.Controls.AutoCompleteFilterMode" />.</exception> /// <see cref="T:Avalonia.Controls.AutoCompleteFilterMode" />.</exception>
/// <remarks> /// <remarks>
/// Use the FilterMode property to specify how possible matches are /// Use the FilterMode property to specify how possible matches are
/// filtered. For example, possible matches can be filtered in a /// filtered. For example, possible matches can be filtered in a
/// predefined or custom way. The search mode is automatically set to /// predefined or custom way. The search mode is automatically set to
/// Custom if you set the ItemFilter property. /// Custom if you set the ItemFilter property.
/// </remarks> /// </remarks>
public AutoCompleteFilterMode FilterMode public AutoCompleteFilterMode FilterMode
{ {
@ -1063,7 +1063,7 @@ namespace Avalonia.Controls
get { return GetValue(WatermarkProperty); } get { return GetValue(WatermarkProperty); }
set { SetValue(WatermarkProperty, value); } set { SetValue(WatermarkProperty, value); }
} }
/// <summary> /// <summary>
/// Gets or sets the custom method that uses user-entered text to filter /// Gets or sets the custom method that uses user-entered text to filter
/// the items specified by the /// the items specified by the
@ -1075,8 +1075,8 @@ namespace Avalonia.Controls
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" /> /// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" />
/// property. The default is null.</value> /// property. The default is null.</value>
/// <remarks> /// <remarks>
/// The filter mode is automatically set to Custom if you set the /// The filter mode is automatically set to Custom if you set the
/// ItemFilter property. /// ItemFilter property.
/// </remarks> /// </remarks>
public AutoCompleteFilterPredicate<object> ItemFilter public AutoCompleteFilterPredicate<object> ItemFilter
{ {
@ -1095,8 +1095,8 @@ namespace Avalonia.Controls
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" /> /// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" />
/// property in a text-based way for display in the drop-down.</value> /// property in a text-based way for display in the drop-down.</value>
/// <remarks> /// <remarks>
/// The search mode is automatically set to Custom if you set the /// The search mode is automatically set to Custom if you set the
/// TextFilter property. /// TextFilter property.
/// </remarks> /// </remarks>
public AutoCompleteFilterPredicate<string> TextFilter public AutoCompleteFilterPredicate<string> TextFilter
{ {
@ -1146,7 +1146,7 @@ namespace Avalonia.Controls
_textBoxSubscriptions = _textBoxSubscriptions =
_textBox.GetObservable(TextBox.TextProperty) _textBox.GetObservable(TextBox.TextProperty)
.Subscribe(_ => OnTextBoxTextChanged()); .Subscribe(_ => OnTextBoxTextChanged());
if (Text != null) if (Text != null)
{ {
UpdateTextValue(Text); UpdateTextValue(Text);
@ -1191,8 +1191,8 @@ namespace Avalonia.Controls
/// <value>The selection adapter used to populate the drop-down with a /// <value>The selection adapter used to populate the drop-down with a
/// list of selectable items.</value> /// list of selectable items.</value>
/// <remarks> /// <remarks>
/// You can use this property when you create an automation peer to /// You can use this property when you create an automation peer to
/// use with AutoCompleteBox or deriving from AutoCompleteBox to /// use with AutoCompleteBox or deriving from AutoCompleteBox to
/// create a custom control. /// create a custom control.
/// </remarks> /// </remarks>
protected ISelectionAdapter SelectionAdapter protected ISelectionAdapter SelectionAdapter
@ -1266,7 +1266,7 @@ namespace Avalonia.Controls
DropDownPopup = null; DropDownPopup = null;
} }
// Set the template parts. Individual part setters remove and add // Set the template parts. Individual part setters remove and add
// any event handlers. // any event handlers.
Popup popup = e.NameScope.Find<Popup>(ElementPopup); Popup popup = e.NameScope.Find<Popup>(ElementPopup);
if (popup != null) if (popup != null)
@ -1277,7 +1277,7 @@ namespace Avalonia.Controls
SelectionAdapter = GetSelectionAdapterPart(e.NameScope); SelectionAdapter = GetSelectionAdapterPart(e.NameScope);
TextBox = e.NameScope.Find<TextBox>(ElementTextBox); TextBox = e.NameScope.Find<TextBox>(ElementTextBox);
// If the drop down property indicates that the popup is open, // If the drop down property indicates that the popup is open,
// flip its value to invoke the changed handler. // flip its value to invoke the changed handler.
if (IsDropDownOpen && DropDownPopup != null && !DropDownPopup.IsOpen) if (IsDropDownOpen && DropDownPopup != null && !DropDownPopup.IsOpen)
@ -1377,7 +1377,7 @@ namespace Avalonia.Controls
base.OnLostFocus(e); base.OnLostFocus(e);
FocusChanged(HasFocus()); FocusChanged(HasFocus());
} }
/// <summary> /// <summary>
/// Determines whether the text box or drop-down portion of the /// Determines whether the text box or drop-down portion of the
/// <see cref="T:Avalonia.Controls.AutoCompleteBox" /> control has /// <see cref="T:Avalonia.Controls.AutoCompleteBox" /> control has
@ -1397,7 +1397,7 @@ namespace Avalonia.Controls
return true; return true;
} }
// This helps deal with popups that may not be in the same // This helps deal with popups that may not be in the same
// visual tree // visual tree
IVisual parent = focused.GetVisualParent(); IVisual parent = focused.GetVisualParent();
if (parent == null) if (parent == null)
@ -1417,14 +1417,14 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Handles the FocusChanged event. /// Handles the FocusChanged event.
/// </summary> /// </summary>
/// <param name="hasFocus">A value indicating whether the control /// <param name="hasFocus">A value indicating whether the control
/// currently has the focus.</param> /// currently has the focus.</param>
private void FocusChanged(bool hasFocus) private void FocusChanged(bool hasFocus)
{ {
// The OnGotFocus & OnLostFocus are asynchronously and cannot // The OnGotFocus & OnLostFocus are asynchronously and cannot
// reliably tell you that have the focus. All they do is let you // reliably tell you that have the focus. All they do is let you
// know that the focus changed sometime in the past. To determine // know that the focus changed sometime in the past. To determine
// if you currently have the focus you need to do consult the // if you currently have the focus you need to do consult the
// FocusManager (see HasFocus()). // FocusManager (see HasFocus()).
bool wasFocused = _isFocused; bool wasFocused = _isFocused;
@ -1432,7 +1432,7 @@ namespace Avalonia.Controls
if (hasFocus) if (hasFocus)
{ {
if (!wasFocused && TextBox != null && TextBoxSelectionLength <= 0) if (!wasFocused && TextBox != null && TextBoxSelectionLength <= 0)
{ {
TextBox.Focus(); TextBox.Focus();
@ -1464,10 +1464,10 @@ namespace Avalonia.Controls
/// property. /// property.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// If the event is canceled, by setting the PopulatingEventArgs.Cancel /// If the event is canceled, by setting the PopulatingEventArgs.Cancel
/// property to true, the AutoCompleteBox will not automatically /// property to true, the AutoCompleteBox will not automatically
/// populate the selection adapter contained in the drop-down. /// populate the selection adapter contained in the drop-down.
/// In this case, if you want possible matches to appear, you must /// In this case, if you want possible matches to appear, you must
/// provide the logic for populating the selection adapter. /// provide the logic for populating the selection adapter.
/// </remarks> /// </remarks>
public event EventHandler<PopulatingEventArgs> Populating; public event EventHandler<PopulatingEventArgs> Populating;
@ -1710,9 +1710,9 @@ namespace Avalonia.Controls
return; return;
} }
// The Populated event enables advanced, custom filtering. The // The Populated event enables advanced, custom filtering. The
// client needs to directly update the ItemsSource collection or // client needs to directly update the ItemsSource collection or
// call the Populate method on the control to continue the // call the Populate method on the control to continue the
// display process if Cancel is set to true. // display process if Cancel is set to true.
PopulatingEventArgs populating = new PopulatingEventArgs(SearchText); PopulatingEventArgs populating = new PopulatingEventArgs(SearchText);
OnPopulating(populating); OnPopulating(populating);
@ -1772,7 +1772,7 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Private method that directly opens the popup, checks the expander /// Private method that directly opens the popup, checks the expander
/// button, and then fires the Opened event. /// button, and then fires the Opened event.
/// </summary> /// </summary>
private void OpenDropDown() private void OpenDropDown()
@ -1786,7 +1786,7 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Private method that directly closes the popup, flips the Checked /// Private method that directly closes the popup, flips the Checked
/// value, and then fires the Closed event. /// value, and then fires the Closed event.
/// </summary> /// </summary>
private void CloseDropDown() private void CloseDropDown()
@ -1806,7 +1806,7 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Formats an Item for text comparisons based on Converter /// Formats an Item for text comparisons based on Converter
/// and ConverterCulture properties. /// and ConverterCulture properties.
/// </summary> /// </summary>
/// <param name="value">The object to format.</param> /// <param name="value">The object to format.</param>
@ -1853,8 +1853,8 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Handle the TextChanged event that is directly attached to the /// Handle the TextChanged event that is directly attached to the
/// TextBox part. This ensures that only user initiated actions will /// TextBox part. This ensures that only user initiated actions will
/// result in an AutoCompleteBox suggestion and operation. /// result in an AutoCompleteBox suggestion and operation.
/// </summary> /// </summary>
private void OnTextBoxTextChanged() private void OnTextBoxTextChanged()
@ -1868,8 +1868,8 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Updates both the text box value and underlying text dependency /// Updates both the text box value and underlying text dependency
/// property value if and when they change. Automatically fires the /// property value if and when they change. Automatically fires the
/// text changed events when there is a change. /// text changed events when there is a change.
/// </summary> /// </summary>
/// <param name="value">The new string value.</param> /// <param name="value">The new string value.</param>
@ -1879,15 +1879,15 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Updates both the text box value and underlying text dependency /// Updates both the text box value and underlying text dependency
/// property value if and when they change. Automatically fires the /// property value if and when they change. Automatically fires the
/// text changed events when there is a change. /// text changed events when there is a change.
/// </summary> /// </summary>
/// <param name="value">The new string value.</param> /// <param name="value">The new string value.</param>
/// <param name="userInitiated">A nullable bool value indicating whether /// <param name="userInitiated">A nullable bool value indicating whether
/// the action was user initiated. In a user initiated mode, the /// the action was user initiated. In a user initiated mode, the
/// underlying text dependency property is updated. In a non-user /// underlying text dependency property is updated. In a non-user
/// interaction, the text box value is updated. When user initiated is /// interaction, the text box value is updated. When user initiated is
/// null, all values are updated.</param> /// null, all values are updated.</param>
private void UpdateTextValue(string value, bool? userInitiated) private void UpdateTextValue(string value, bool? userInitiated)
{ {
@ -1920,16 +1920,16 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Handle the update of the text for the control from any source, /// Handle the update of the text for the control from any source,
/// including the TextBox part and the Text dependency property. /// including the TextBox part and the Text dependency property.
/// </summary> /// </summary>
/// <param name="newText">The new text.</param> /// <param name="newText">The new text.</param>
/// <param name="userInitiated">A value indicating whether the update /// <param name="userInitiated">A value indicating whether the update
/// is a user-initiated action. This should be a True value when the /// is a user-initiated action. This should be a True value when the
/// TextUpdated method is called from a TextBox event handler.</param> /// TextUpdated method is called from a TextBox event handler.</param>
private void TextUpdated(string newText, bool userInitiated) private void TextUpdated(string newText, bool userInitiated)
{ {
// Only process this event if it is coming from someone outside // Only process this event if it is coming from someone outside
// setting the Text dependency property directly. // setting the Text dependency property directly.
if (_ignoreTextPropertyChange > 0) if (_ignoreTextPropertyChange > 0)
{ {
@ -1942,8 +1942,8 @@ namespace Avalonia.Controls
newText = string.Empty; newText = string.Empty;
} }
// The TextBox.TextChanged event was not firing immediately and // The TextBox.TextChanged event was not firing immediately and
// was causing an immediate update, even with wrapping. If there is // was causing an immediate update, even with wrapping. If there is
// a selection currently, no update should happen. // a selection currently, no update should happen.
if (IsTextCompletionEnabled && TextBox != null && TextBoxSelectionLength > 0 && TextBoxSelectionStart != TextBox.Text.Length) if (IsTextCompletionEnabled && TextBox != null && TextBoxSelectionLength > 0 && TextBoxSelectionStart != TextBox.Text.Length)
{ {
@ -1988,7 +1988,7 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// A simple helper method to clear the view and ensure that a view /// A simple helper method to clear the view and ensure that a view
/// object is always present and not null. /// object is always present and not null.
/// </summary> /// </summary>
private void ClearView() private void ClearView()
@ -2004,7 +2004,7 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Walks through the items enumeration. Performance is not going to be /// Walks through the items enumeration. Performance is not going to be
/// perfect with the current implementation. /// perfect with the current implementation.
/// </summary> /// </summary>
private void RefreshView() private void RefreshView()
@ -2044,7 +2044,7 @@ namespace Avalonia.Controls
if (view_count > view_index && _view[view_index] != item) if (view_count > view_index && _view[view_index] != item)
{ {
// Replace item // Replace item
// Unfortunately replacing via index throws a fatal // Unfortunately replacing via index throws a fatal
// exception: View[view_index] = item; // exception: View[view_index] = item;
// Cost: O(n) vs O(1) // Cost: O(n) vs O(1)
_view.RemoveAt(view_index); _view.RemoveAt(view_index);
@ -2083,8 +2083,8 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Handle any change to the ItemsSource dependency property, update /// Handle any change to the ItemsSource dependency property, update
/// the underlying ObservableCollection view, and set the selection /// the underlying ObservableCollection view, and set the selection
/// adapter's ItemsSource to the view if appropriate. /// adapter's ItemsSource to the view if appropriate.
/// </summary> /// </summary>
/// <param name="newValue">The new enumerable reference.</param> /// <param name="newValue">The new enumerable reference.</param>
@ -2176,14 +2176,14 @@ namespace Avalonia.Controls
/// possible matches in the drop-down. /// possible matches in the drop-down.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// Call this method when you are providing custom population of /// Call this method when you are providing custom population of
/// the drop-down portion of the AutoCompleteBox, to signal the control /// the drop-down portion of the AutoCompleteBox, to signal the control
/// that you are done with the population process. /// that you are done with the population process.
/// Typically, you use PopulateComplete when the population process /// Typically, you use PopulateComplete when the population process
/// is a long-running process and you want to cancel built-in filtering /// is a long-running process and you want to cancel built-in filtering
/// of the ItemsSource items. In this case, you can handle the /// of the ItemsSource items. In this case, you can handle the
/// Populated event and set PopulatingEventArgs.Cancel to true. /// Populated event and set PopulatingEventArgs.Cancel to true.
/// When the long-running process has completed you call /// When the long-running process has completed you call
/// PopulateComplete to indicate the drop-down is populated. /// PopulateComplete to indicate the drop-down is populated.
/// </remarks> /// </remarks>
public void PopulateComplete() public void PopulateComplete()
@ -2223,7 +2223,7 @@ namespace Avalonia.Controls
/// item values for an exact match. Will update the SelectedItem value. /// item values for an exact match. Will update the SelectedItem value.
/// </summary> /// </summary>
/// <param name="userInitiated">A value indicating whether the operation /// <param name="userInitiated">A value indicating whether the operation
/// was user initiated. Text completion will not be performed when not /// was user initiated. Text completion will not be performed when not
/// directly initiated by the user.</param> /// directly initiated by the user.</param>
private void UpdateTextCompletion(bool userInitiated) private void UpdateTextCompletion(bool userInitiated)
{ {
@ -2231,9 +2231,9 @@ namespace Avalonia.Controls
object newSelectedItem = null; object newSelectedItem = null;
string text = Text; string text = Text;
// Text search is StartsWith explicit and only when enabled, in // Text search is StartsWith explicit and only when enabled, in
// line with WPF's ComboBox lookup. When in use it will associate // line with WPF's ComboBox lookup. When in use it will associate
// a Value with the Text if it is found in ItemsSource. This is // a Value with the Text if it is found in ItemsSource. This is
// only valid when there is data and the user initiated the action. // only valid when there is data and the user initiated the action.
if (_view.Count > 0) if (_view.Count > 0)
{ {
@ -2243,11 +2243,11 @@ namespace Avalonia.Controls
int selectionStart = TextBoxSelectionStart; int selectionStart = TextBoxSelectionStart;
if (selectionStart == text.Length && selectionStart > _textSelectionStart) if (selectionStart == text.Length && selectionStart > _textSelectionStart)
{ {
// When the FilterMode dependency property is set to // When the FilterMode dependency property is set to
// either StartsWith or StartsWithCaseSensitive, the // either StartsWith or StartsWithCaseSensitive, the
// first item in the view is used. This will improve // first item in the view is used. This will improve
// performance on the lookup. It assumes that the // performance on the lookup. It assumes that the
// FilterMode the user has selected is an acceptable // FilterMode the user has selected is an acceptable
// case sensitive matching function for their scenario. // case sensitive matching function for their scenario.
object top = FilterMode == AutoCompleteFilterMode.StartsWith || FilterMode == AutoCompleteFilterMode.StartsWithCaseSensitive object top = FilterMode == AutoCompleteFilterMode.StartsWith || FilterMode == AutoCompleteFilterMode.StartsWithCaseSensitive
? _view[0] ? _view[0]
@ -2268,16 +2268,16 @@ namespace Avalonia.Controls
// Select the text past the user's caret // Select the text past the user's caret
TextBox.SelectionStart = currentLength; TextBox.SelectionStart = currentLength;
TextBox.SelectionEnd = topString.Length; TextBox.SelectionEnd = topString.Length;
} }
} }
} }
} }
else else
{ {
// Perform an exact string lookup for the text. This is a // Perform an exact string lookup for the text. This is a
// design change from the original Toolkit release when the // design change from the original Toolkit release when the
// IsTextCompletionEnabled property behaved just like the // IsTextCompletionEnabled property behaved just like the
// WPF ComboBox's IsTextSearchEnabled property. // WPF ComboBox's IsTextSearchEnabled property.
// //
// This change provides the behavior that most people expect // This change provides the behavior that most people expect
@ -2306,12 +2306,12 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Attempts to look through the view and locate the specific exact /// Attempts to look through the view and locate the specific exact
/// text match. /// text match.
/// </summary> /// </summary>
/// <param name="searchText">The search text.</param> /// <param name="searchText">The search text.</param>
/// <param name="view">The view reference.</param> /// <param name="view">The view reference.</param>
/// <param name="predicate">The predicate to use for the partial or /// <param name="predicate">The predicate to use for the partial or
/// exact match.</param> /// exact match.</param>
/// <returns>Returns the object or null.</returns> /// <returns>Returns the object or null.</returns>
private object TryGetMatch(string searchText, AvaloniaList<object> view, AutoCompleteFilterPredicate<string> predicate) private object TryGetMatch(string searchText, AvaloniaList<object> view, AutoCompleteFilterPredicate<string> predicate)
@ -2413,13 +2413,13 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// A predefined set of filter functions for the known, built-in /// A predefined set of filter functions for the known, built-in
/// AutoCompleteFilterMode enumeration values. /// AutoCompleteFilterMode enumeration values.
/// </summary> /// </summary>
private static class AutoCompleteSearch private static class AutoCompleteSearch
{ {
/// <summary> /// <summary>
/// Index function that retrieves the filter for the provided /// Index function that retrieves the filter for the provided
/// AutoCompleteFilterMode. /// AutoCompleteFilterMode.
/// </summary> /// </summary>
/// <param name="FilterMode">The built-in search mode.</param> /// <param name="FilterMode">The built-in search mode.</param>
@ -2472,8 +2472,8 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// An implementation of the Contains member of string that takes in a /// An implementation of the Contains member of string that takes in a
/// string comparison. The traditional .NET string Contains member uses /// string comparison. The traditional .NET string Contains member uses
/// StringComparison.Ordinal. /// StringComparison.Ordinal.
/// </summary> /// </summary>
/// <param name="s">The string.</param> /// <param name="s">The string.</param>
@ -2530,7 +2530,7 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Check if the prefix is contained in the string value. The current /// Check if the prefix is contained in the string value. The current
/// culture's case insensitive string comparison operator is used. /// culture's case insensitive string comparison operator is used.
/// </summary> /// </summary>
/// <param name="text">The AutoCompleteBox prefix text.</param> /// <param name="text">The AutoCompleteBox prefix text.</param>
@ -2647,7 +2647,7 @@ namespace Avalonia.Controls
get { return GetValue(ValueProperty); } get { return GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); } set { SetValue(ValueProperty, value); }
} }
#endregion public string Value #endregion public string Value
/// <summary> /// <summary>
@ -2690,7 +2690,7 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Updates the data context of the framework element and returns the /// Updates the data context of the framework element and returns the
/// updated binding value. /// updated binding value.
/// </summary> /// </summary>
/// <param name="o">The object to use as the data context.</param> /// <param name="o">The object to use as the data context.</param>
@ -2710,7 +2710,7 @@ namespace Avalonia.Controls
} }
/// <summary> /// <summary>
/// Updates the data context of the framework element and returns the /// Updates the data context of the framework element and returns the
/// updated binding value. /// updated binding value.
/// </summary> /// </summary>
/// <param name="o">The object to use as the data context.</param> /// <param name="o">The object to use as the data context.</param>

Loading…
Cancel
Save