@ -69,7 +69,7 @@ namespace Avalonia.Controls
/// </summary>
/// <value>The text that is used to determine which items to display in
/// the <see cref="T:Avalonia.Controls.AutoCompleteBox" />.</value>
public string Parameter { get ; private set ; }
public string? Parameter { get ; private set ; }
/// <summary>
/// Initializes a new instance of the
@ -79,7 +79,7 @@ namespace Avalonia.Controls
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.SearchText" />
/// property, which is used to filter items for the
/// <see cref="T:Avalonia.Controls.AutoCompleteBox" /> control.</param>
public PopulatingEventArgs ( string parameter )
public PopulatingEventArgs ( string? parameter )
{
Parameter = parameter ;
}
@ -98,7 +98,7 @@ namespace Avalonia.Controls
/// <typeparam name="T">The type used for filtering the
/// <see cref="T:Avalonia.Controls.AutoCompleteBox" />. This type can
/// be either a string or an object.</typeparam>
public delegate bool AutoCompleteFilterPredicate < T > ( string search , T item ) ;
public delegate bool AutoCompleteFilterPredicate < T > ( string? search , T item ) ;
/// <summary>
/// Specifies how text in the text box portion of the
@ -245,7 +245,7 @@ namespace Avalonia.Controls
/// <see cref="T:Avalonia.Controls.AutoCompleteBox" />.
/// This type can be either a string or an object.
/// </typeparam>
public delegate string AutoCompleteSelector < T > ( string search , T item ) ;
public delegate string AutoCompleteSelector < T > ( string? search , T item ) ;
/// <summary>
/// Represents a control that provides a text box for user input and a
@ -275,19 +275,19 @@ namespace Avalonia.Controls
/// </summary>
private const string ElementTextBox = "PART_TextBox" ;
private IEnumerable _ itemsEnumerable ;
private IEnumerable ? _ itemsEnumerable ;
/// <summary>
/// Gets or sets a local cached copy of the items data.
/// </summary>
private List < object > _ items ;
private List < object > ? _ items ;
/// <summary>
/// Gets or sets the observable collection that contains references to
/// all of the items in the generated view of data that is provided to
/// the selection-style control adapter.
/// </summary>
private AvaloniaList < object > _ view ;
private AvaloniaList < object > ? _ view ;
/// <summary>
/// Gets or sets a value to ignore a number of pending change handlers.
@ -338,7 +338,7 @@ namespace Avalonia.Controls
/// Gets or sets the DispatcherTimer used for the MinimumPopulateDelay
/// condition for auto completion.
/// </summary>
private DispatcherTimer _d elayTimer ;
private DispatcherTimer ? _d elayTimer ;
/// <summary>
/// Gets or sets a value indicating whether a read-only dependency
@ -351,47 +351,47 @@ namespace Avalonia.Controls
/// <summary>
/// The TextBox template part.
/// </summary>
private TextBox _ textBox ;
private IDisposable _ textBoxSubscriptions ;
private TextBox ? _ textBox ;
private IDisposable ? _ textBoxSubscriptions ;
/// <summary>
/// The SelectionAdapter.
/// </summary>
private ISelectionAdapter _ adapter ;
private ISelectionAdapter ? _ adapter ;
/// <summary>
/// A control that can provide updated string values from a binding.
/// </summary>
private BindingEvaluator < string > _ valueBindingEvaluator ;
private BindingEvaluator < string > ? _ valueBindingEvaluator ;
/// <summary>
/// A weak subscription for the collection changed event.
/// </summary>
private IDisposable _ collectionChangeSubscription ;
private IDisposable ? _ collectionChangeSubscription ;
private Func < string , CancellationToken , Task < IEnumerable < object > > > _ asyncPopulator ;
private CancellationTokenSource _ populationCancellationTokenSource ;
private Func < string? , CancellationToken , Task < IEnumerable < object > > > ? _ asyncPopulator ;
private CancellationTokenSource ? _ populationCancellationTokenSource ;
private bool _ itemTemplateIsFromValueMemberBinding = true ;
private bool _ settingItemTemplateFromValueMemberBinding ;
private object _ selectedItem ;
private object? _ selectedItem ;
private bool _ isDropDownOpen ;
private bool _ isFocused = false ;
private string _ text = string . Empty ;
private string _ searchText = string . Empty ;
private string? _ text = string . Empty ;
private string? _ searchText = string . Empty ;
private AutoCompleteFilterPredicate < object > _ itemFilter ;
private AutoCompleteFilterPredicate < string > _ textFilter = AutoCompleteSearch . GetFilter ( AutoCompleteFilterMode . StartsWith ) ;
private AutoCompleteFilterPredicate < object? > ? _ itemFilter ;
private AutoCompleteFilterPredicate < string? > ? _ textFilter = AutoCompleteSearch . GetFilter ( AutoCompleteFilterMode . StartsWith ) ;
private AutoCompleteSelector < object > _ itemSelector ;
private AutoCompleteSelector < string > _ textSelector ;
private AutoCompleteSelector < object > ? _ itemSelector ;
private AutoCompleteSelector < string? > ? _ textSelector ;
public static readonly RoutedEvent < SelectionChangedEventArgs > SelectionChangedEvent =
RoutedEvent . Register < SelectionChangedEventArgs > ( nameof ( SelectionChanged ) , RoutingStrategies . Bubble , typeof ( AutoCompleteBox ) ) ;
public static readonly StyledProperty < string > WatermarkProperty =
public static readonly StyledProperty < string? > WatermarkProperty =
TextBox . WatermarkProperty . AddOwner < AutoCompleteBox > ( ) ;
/// <summary>
@ -479,8 +479,8 @@ namespace Avalonia.Controls
/// <value>The identifier the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.SelectedItem" />
/// dependency property.</value>
public static readonly DirectProperty < AutoCompleteBox , object > SelectedItemProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , object > (
public static readonly DirectProperty < AutoCompleteBox , object? > SelectedItemProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , object? > (
nameof ( SelectedItem ) ,
o = > o . SelectedItem ,
( o , v ) = > o . SelectedItem = v ,
@ -495,7 +495,7 @@ namespace Avalonia.Controls
/// <value>The identifier for the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.Text" />
/// dependency property.</value>
public static readonly DirectProperty < AutoCompleteBox , string > TextProperty =
public static readonly DirectProperty < AutoCompleteBox , string? > TextProperty =
TextBlock . TextProperty . AddOwnerWithDataValidation < AutoCompleteBox > (
o = > o . Text ,
( o , v ) = > o . Text = v ,
@ -510,8 +510,8 @@ namespace Avalonia.Controls
/// <value>The identifier for the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.SearchText" />
/// dependency property.</value>
public static readonly DirectProperty < AutoCompleteBox , string > SearchTextProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , string > (
public static readonly DirectProperty < AutoCompleteBox , string? > SearchTextProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , string? > (
nameof ( SearchText ) ,
o = > o . SearchText ,
unsetValue : string . Empty ) ;
@ -535,8 +535,8 @@ namespace Avalonia.Controls
/// <value>The identifier for the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemFilter" />
/// dependency property.</value>
public static readonly DirectProperty < AutoCompleteBox , AutoCompleteFilterPredicate < object > > ItemFilterProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , AutoCompleteFilterPredicate < object > > (
public static readonly DirectProperty < AutoCompleteBox , AutoCompleteFilterPredicate < object? > ? > ItemFilterProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , AutoCompleteFilterPredicate < object? > ? > (
nameof ( ItemFilter ) ,
o = > o . ItemFilter ,
( o , v ) = > o . ItemFilter = v ) ;
@ -549,8 +549,8 @@ namespace Avalonia.Controls
/// <value>The identifier for the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.TextFilter" />
/// dependency property.</value>
public static readonly DirectProperty < AutoCompleteBox , AutoCompleteFilterPredicate < string > > TextFilterProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , AutoCompleteFilterPredicate < string > > (
public static readonly DirectProperty < AutoCompleteBox , AutoCompleteFilterPredicate < string? > ? > TextFilterProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , AutoCompleteFilterPredicate < string? > ? > (
nameof ( TextFilter ) ,
o = > o . TextFilter ,
( o , v ) = > o . TextFilter = v ,
@ -564,8 +564,8 @@ namespace Avalonia.Controls
/// <value>The identifier for the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemSelector" />
/// dependency property.</value>
public static readonly DirectProperty < AutoCompleteBox , AutoCompleteSelector < object > > ItemSelectorProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , AutoCompleteSelector < object > > (
public static readonly DirectProperty < AutoCompleteBox , AutoCompleteSelector < object > ? > ItemSelectorProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , AutoCompleteSelector < object > ? > (
nameof ( ItemSelector ) ,
o = > o . ItemSelector ,
( o , v ) = > o . ItemSelector = v ) ;
@ -578,8 +578,8 @@ namespace Avalonia.Controls
/// <value>The identifier for the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.TextSelector" />
/// dependency property.</value>
public static readonly DirectProperty < AutoCompleteBox , AutoCompleteSelector < string > > TextSelectorProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , AutoCompleteSelector < string > > (
public static readonly DirectProperty < AutoCompleteBox , AutoCompleteSelector < string? > ? > TextSelectorProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , AutoCompleteSelector < string? > ? > (
nameof ( TextSelector ) ,
o = > o . TextSelector ,
( o , v ) = > o . TextSelector = v ) ;
@ -592,14 +592,14 @@ namespace Avalonia.Controls
/// <value>The identifier for the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" />
/// dependency property.</value>
public static readonly DirectProperty < AutoCompleteBox , IEnumerable > ItemsProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , IEnumerable > (
public static readonly DirectProperty < AutoCompleteBox , IEnumerable ? > ItemsProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , IEnumerable ? > (
nameof ( Items ) ,
o = > o . Items ,
( o , v ) = > o . Items = v ) ;
public static readonly DirectProperty < AutoCompleteBox , Func < string , CancellationToken , Task < IEnumerable < object > > > > AsyncPopulatorProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , Func < string , CancellationToken , Task < IEnumerable < object > > > > (
public static readonly DirectProperty < AutoCompleteBox , Func < string? , CancellationToken , Task < IEnumerable < object > > > ? > AsyncPopulatorProperty =
AvaloniaProperty . RegisterDirect < AutoCompleteBox , Func < string? , CancellationToken , Task < IEnumerable < object > > > ? > (
nameof ( AsyncPopulator ) ,
o = > o . AsyncPopulator ,
( o , v ) = > o . AsyncPopulator = v ) ;
@ -640,7 +640,7 @@ namespace Avalonia.Controls
/// <param name="e">The event data.</param>
private void OnControlIsEnabledChanged ( AvaloniaPropertyChangedEventArgs e )
{
bool isEnabled = ( bool ) e . NewValue ;
bool isEnabled = ( bool ) e . NewValue ! ;
if ( ! isEnabled )
{
IsDropDownOpen = false ;
@ -655,7 +655,7 @@ namespace Avalonia.Controls
/// <param name="e">Event arguments.</param>
private void OnMinimumPopulateDelayChanged ( AvaloniaPropertyChangedEventArgs e )
{
var newValue = ( TimeSpan ) e . NewValue ;
var newValue = ( TimeSpan ) e . NewValue ! ;
// Stop any existing timer
if ( _d elayTimer ! = null )
@ -695,8 +695,8 @@ namespace Avalonia.Controls
return ;
}
bool oldValue = ( bool ) e . OldValue ;
bool newValue = ( bool ) e . NewValue ;
bool oldValue = ( bool ) e . OldValue ! ;
bool newValue = ( bool ) e . NewValue ! ;
if ( newValue )
{
@ -750,7 +750,7 @@ namespace Avalonia.Controls
/// <param name="e">Event arguments.</param>
private void OnTextPropertyChanged ( AvaloniaPropertyChangedEventArgs e )
{
TextUpdated ( ( string ) e . NewValue , false ) ;
TextUpdated ( ( string? ) e . NewValue , false ) ;
}
private void OnSearchTextPropertyChanged ( AvaloniaPropertyChangedEventArgs e )
@ -778,7 +778,7 @@ namespace Avalonia.Controls
/// <param name="e">Event arguments.</param>
private void OnFilterModePropertyChanged ( AvaloniaPropertyChangedEventArgs e )
{
AutoCompleteFilterMode mode = ( AutoCompleteFilterMode ) e . NewValue ;
AutoCompleteFilterMode mode = ( AutoCompleteFilterMode ) e . NewValue ! ;
// Sets the filter predicate for the new value
TextFilter = AutoCompleteSearch . GetFilter ( mode ) ;
@ -790,7 +790,7 @@ namespace Avalonia.Controls
/// <param name="e">Event arguments.</param>
private void OnItemFilterPropertyChanged ( AvaloniaPropertyChangedEventArgs e )
{
AutoCompleteFilterPredicate < object > value = e . NewValue as AutoCompleteFilterPredicate < object > ;
var value = e . NewValue as AutoCompleteFilterPredicate < object > ;
// If null, revert to the "None" predicate
if ( value = = null )
@ -810,7 +810,7 @@ namespace Avalonia.Controls
/// <param name="e">Event arguments.</param>
private void OnItemsPropertyChanged ( AvaloniaPropertyChangedEventArgs e )
{
OnItemsChanged ( ( IEnumerable ) e . NewValue ) ;
OnItemsChanged ( ( IEnumerable ? ) e . NewValue ) ;
}
private void OnItemTemplatePropertyChanged ( AvaloniaPropertyChangedEventArgs e )
@ -818,7 +818,7 @@ namespace Avalonia.Controls
if ( ! _ settingItemTemplateFromValueMemberBinding )
_ itemTemplateIsFromValueMemberBinding = false ;
}
private void OnValueMemberBindingChanged ( IBinding value )
private void OnValueMemberBindingChanged ( IBinding ? value )
{
if ( _ itemTemplateIsFromValueMemberBinding )
{
@ -828,7 +828,8 @@ namespace Avalonia.Controls
( o , _ ) = >
{
var control = new ContentControl ( ) ;
control . Bind ( ContentControl . ContentProperty , value ) ;
if ( value is not null )
control . Bind ( ContentControl . ContentProperty , value ) ;
return control ;
} ) ;
@ -975,7 +976,7 @@ namespace Avalonia.Controls
/// <value>The <see cref="T:Avalonia.Data.IBinding" /> object used
/// when binding to a collection property.</value>
[AssignBinding]
public IBinding ValueMemberBinding
public IBinding ? ValueMemberBinding
{
get { return _ valueBindingEvaluator ? . ValueBinding ; }
set
@ -998,7 +999,7 @@ namespace Avalonia.Controls
/// then displayed in the text box, the SelectedItem property will be
/// a null reference.
/// </remarks>
public object SelectedItem
public object? SelectedItem
{
get { return _ selectedItem ; }
set { SetAndRaise ( SelectedItemProperty , ref _ selectedItem , value ) ; }
@ -1010,7 +1011,7 @@ namespace Avalonia.Controls
/// </summary>
/// <value>The text in the text box portion of the
/// <see cref="T:Avalonia.Controls.AutoCompleteBox" /> control.</value>
public string Text
public string? Text
{
get { return _ text ; }
set { SetAndRaise ( TextProperty , ref _ text , value ) ; }
@ -1029,7 +1030,7 @@ namespace Avalonia.Controls
/// Text property, but is set after the TextChanged event occurs
/// and before the Populating event.
/// </remarks>
public string SearchText
public string? SearchText
{
get { return _ searchText ; }
private set
@ -1071,7 +1072,7 @@ namespace Avalonia.Controls
set { SetValue ( FilterModeProperty , value ) ; }
}
public string Watermark
public string? Watermark
{
get { return GetValue ( WatermarkProperty ) ; }
set { SetValue ( WatermarkProperty , value ) ; }
@ -1091,7 +1092,7 @@ namespace Avalonia.Controls
/// The filter mode is automatically set to Custom if you set the
/// ItemFilter property.
/// </remarks>
public AutoCompleteFilterPredicate < object > ItemFilter
public AutoCompleteFilterPredicate < object? > ? ItemFilter
{
get { return _ itemFilter ; }
set { SetAndRaise ( ItemFilterProperty , ref _ itemFilter , value ) ; }
@ -1111,7 +1112,7 @@ namespace Avalonia.Controls
/// The search mode is automatically set to Custom if you set the
/// TextFilter property.
/// </remarks>
public AutoCompleteFilterPredicate < string > TextFilter
public AutoCompleteFilterPredicate < string? > ? TextFilter
{
get { return _ textFilter ; }
set { SetAndRaise ( TextFilterProperty , ref _ textFilter , value ) ; }
@ -1127,7 +1128,7 @@ namespace Avalonia.Controls
/// text and one of the items specified by the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" />.
/// </value>
public AutoCompleteSelector < object > ItemSelector
public AutoCompleteSelector < object > ? ItemSelector
{
get { return _ itemSelector ; }
set { SetAndRaise ( ItemSelectorProperty , ref _ itemSelector , value ) ; }
@ -1145,13 +1146,13 @@ namespace Avalonia.Controls
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.ItemsSource" />
/// in a text-based way.
/// </value>
public AutoCompleteSelector < string > TextSelector
public AutoCompleteSelector < string? > ? TextSelector
{
get { return _ textSelector ; }
set { SetAndRaise ( TextSelectorProperty , ref _ textSelector , value ) ; }
}
public Func < string , CancellationToken , Task < IEnumerable < object > > > AsyncPopulator
public Func < string? , CancellationToken , Task < IEnumerable < object > > > ? AsyncPopulator
{
get { return _ asyncPopulator ; }
set { SetAndRaise ( AsyncPopulatorProperty , ref _ asyncPopulator , value ) ; }
@ -1165,7 +1166,7 @@ namespace Avalonia.Controls
/// <value>The collection that is used to generate the items of the
/// drop-down portion of the
/// <see cref="T:Avalonia.Controls.AutoCompleteBox" /> control.</value>
public IEnumerable Items
public IEnumerable ? Items
{
get { return _ itemsEnumerable ; }
set { SetAndRaise ( ItemsProperty , ref _ itemsEnumerable , value ) ; }
@ -1174,12 +1175,12 @@ namespace Avalonia.Controls
/// <summary>
/// Gets or sets the drop down popup control.
/// </summary>
private Popup DropDownPopup { get ; set ; }
private Popup ? DropDownPopup { get ; set ; }
/// <summary>
/// Gets or sets the Text template part.
/// </summary>
private TextBox TextBox
private TextBox ? TextBox
{
get { return _ textBox ; }
set
@ -1243,7 +1244,7 @@ namespace Avalonia.Controls
/// use with AutoCompleteBox or deriving from AutoCompleteBox to
/// create a custom control.
/// </remarks>
protected ISelectionAdapter SelectionAdapter
protected ISelectionAdapter ? SelectionAdapter
{
get { return _ adapter ; }
set
@ -1279,10 +1280,10 @@ namespace Avalonia.Controls
/// A <see cref="T:Avalonia.Controls.ISelectionAdapter" /> object,
/// if possible. Otherwise, null.
/// </returns>
protected virtual ISelectionAdapter GetSelectionAdapterPart ( INameScope nameScope )
protected virtual ISelectionAdapter ? GetSelectionAdapterPart ( INameScope nameScope )
{
ISelectionAdapter adapter = null ;
SelectingItemsControl selector = nameScope . Find < SelectingItemsControl > ( ElementSelector ) ;
ISelectionAdapter ? adapter = null ;
SelectingItemsControl ? selector = nameScope . Find < SelectingItemsControl > ( ElementSelector ) ;
if ( selector ! = null )
{
// Check if it is already an IItemsSelector
@ -1316,7 +1317,7 @@ namespace Avalonia.Controls
// Set the template parts. Individual part setters remove and add
// any event handlers.
Popup popup = e . NameScope . Find < Popup > ( ElementPopup ) ;
Popup ? popup = e . NameScope . Find < Popup > ( ElementPopup ) ;
if ( popup ! = null )
{
DropDownPopup = popup ;
@ -1358,7 +1359,7 @@ namespace Avalonia.Controls
/// that contains the event data.</param>
protected override void OnKeyDown ( KeyEventArgs e )
{
Contract . Requires < ArgumentNullException > ( e ! = null ) ;
_ = e ? ? throw new ArgumentNullException ( nameof ( e ) ) ;
base . OnKeyDown ( e ) ;
@ -1453,7 +1454,7 @@ namespace Avalonia.Controls
/// otherwise, false.</returns>
protected bool HasFocus ( )
{
IVisual focused = FocusManager . Instance . Current ;
IVisual ? focused = FocusManager . Instance ? . Current ;
while ( focused ! = null )
{
@ -1464,11 +1465,11 @@ namespace Avalonia.Controls
// This helps deal with popups that may not be in the same
// visual tree
IVisual parent = focused . GetVisualParent ( ) ;
IVisual ? parent = focused . GetVisualParent ( ) ;
if ( parent = = null )
{
// Try the logical parent.
IControl element = focused as IControl ;
IControl ? element = focused as IControl ;
if ( element ! = null )
{
parent = element . Parent ;
@ -1519,7 +1520,7 @@ namespace Avalonia.Controls
/// Occurs when the text in the text box portion of the
/// <see cref="T:Avalonia.Controls.AutoCompleteBox" /> changes.
/// </summary>
public event EventHandler TextChanged ;
public event EventHandler ? TextChanged ;
/// <summary>
/// Occurs when the
@ -1535,7 +1536,7 @@ namespace Avalonia.Controls
/// In this case, if you want possible matches to appear, you must
/// provide the logic for populating the selection adapter.
/// </remarks>
public event EventHandler < PopulatingEventArgs > Populating ;
public event EventHandler < PopulatingEventArgs > ? Populating ;
/// <summary>
/// Occurs when the
@ -1544,35 +1545,35 @@ namespace Avalonia.Controls
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.Text" />
/// property.
/// </summary>
public event EventHandler < PopulatedEventArgs > Populated ;
public event EventHandler < PopulatedEventArgs > ? Populated ;
/// <summary>
/// Occurs when the value of the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.IsDropDownOpen" />
/// property is changing from false to true.
/// </summary>
public event EventHandler < CancelEventArgs > DropDownOpening ;
public event EventHandler < CancelEventArgs > ? DropDownOpening ;
/// <summary>
/// Occurs when the value of the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.IsDropDownOpen" />
/// property has changed from false to true and the drop-down is open.
/// </summary>
public event EventHandler DropDownOpened ;
public event EventHandler ? DropDownOpened ;
/// <summary>
/// Occurs when the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.IsDropDownOpen" />
/// property is changing from true to false.
/// </summary>
public event EventHandler < CancelEventArgs > DropDownClosing ;
public event EventHandler < CancelEventArgs > ? DropDownClosing ;
/// <summary>
/// Occurs when the
/// <see cref="P:Avalonia.Controls.AutoCompleteBox.IsDropDownOpen" />
/// property was changed from true to false and the drop-down is open.
/// </summary>
public event EventHandler DropDownClosed ;
public event EventHandler ? DropDownClosed ;
/// <summary>
/// Occurs when the selected item in the drop-down portion of the
@ -1740,7 +1741,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="sender">The source object.</param>
/// <param name="e">The event data.</param>
private void DropDownPopup_Closed ( object sender , EventArgs e )
private void DropDownPopup_Closed ( object? sender , EventArgs e )
{
// Force the drop down dependency property to be false.
if ( IsDropDownOpen )
@ -1760,7 +1761,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="sender">The source object.</param>
/// <param name="e">The event arguments.</param>
private void PopulateDropDown ( object sender , EventArgs e )
private void PopulateDropDown ( object? sender , EventArgs e )
{
if ( _d elayTimer ! = null )
{
@ -1786,7 +1787,7 @@ namespace Avalonia.Controls
PopulateComplete ( ) ;
}
}
private bool TryPopulateAsync ( string searchText )
private bool TryPopulateAsync ( string? searchText )
{
_ populationCancellationTokenSource ? . Cancel ( false ) ;
_ populationCancellationTokenSource ? . Dispose ( ) ;
@ -1804,12 +1805,12 @@ namespace Avalonia.Controls
return true ;
}
private async Task PopulateAsync ( string searchText , CancellationToken cancellationToken )
private async Task PopulateAsync ( string? searchText , CancellationToken cancellationToken )
{
try
{
IEnumerable < object > result = await _ asyncPopulator . Invoke ( searchText , cancellationToken ) ;
IEnumerable < object > result = await _ asyncPopulator ! . Invoke ( searchText , cancellationToken ) ;
var resultList = result . ToList ( ) ;
if ( cancellationToken . IsCancellationRequested )
@ -1878,9 +1879,9 @@ namespace Avalonia.Controls
/// <param name="clearDataContext">A value indicating whether to clear
/// the data context after the lookup is performed.</param>
/// <returns>Formatted Value.</returns>
private string FormatValue ( object value , bool clearDataContext )
private string? FormatValue ( object? value , bool clearDataContext )
{
string result = FormatValue ( value ) ;
string? result = FormatValue ( value ) ;
if ( clearDataContext & & _ valueBindingEvaluator ! = null )
{
_ valueBindingEvaluator . ClearDataContext ( ) ;
@ -1902,7 +1903,7 @@ namespace Avalonia.Controls
/// <remarks>
/// Override this method to provide a custom string conversion.
/// </remarks>
protected virtual string FormatValue ( object value )
protected virtual string? FormatValue ( object? value )
{
if ( _ valueBindingEvaluator ! = null )
{
@ -1923,7 +1924,7 @@ namespace Avalonia.Controls
Dispatcher . UIThread . Post ( ( ) = >
{
// Call the central updated text method as a user-initiated action
TextUpdated ( _ textBox . Text , true ) ;
TextUpdated ( _ textBox ! . Text , true ) ;
} ) ;
}
@ -1933,7 +1934,7 @@ namespace Avalonia.Controls
/// text changed events when there is a change.
/// </summary>
/// <param name="value">The new string value.</param>
private void UpdateTextValue ( string value )
private void UpdateTextValue ( string? value )
{
UpdateTextValue ( value , null ) ;
}
@ -1949,7 +1950,7 @@ namespace Avalonia.Controls
/// underlying text dependency property is updated. In a non-user
/// interaction, the text box value is updated. When user initiated is
/// null, all values are updated.</param>
private void UpdateTextValue ( string value , bool? userInitiated )
private void UpdateTextValue ( string? value , bool? userInitiated )
{
bool callTextChanged = false ;
// Update the Text dependency property
@ -1987,7 +1988,7 @@ namespace Avalonia.Controls
/// <param name="userInitiated">A value indicating whether the update
/// is a user-initiated action. This should be a True value when the
/// 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
// setting the Text dependency property directly.
@ -2087,7 +2088,7 @@ namespace Avalonia.Controls
bool objectFiltering = FilterMode = = AutoCompleteFilterMode . Custom & & TextFilter = = null ;
int view_index = 0 ;
int view_count = _ view . Count ;
int view_count = _ view ! . Count ;
List < object > items = _ items ;
foreach ( object item in items )
{
@ -2096,7 +2097,7 @@ namespace Avalonia.Controls
{
if ( stringFiltering )
{
inResults = TextFilter ( text , FormatValue ( item ) ) ;
inResults = TextFilter ! ( text , FormatValue ( item ) ) ;
}
else
{
@ -2166,7 +2167,7 @@ namespace Avalonia.Controls
/// adapter's ItemsSource to the view if appropriate.
/// </summary>
/// <param name="newValue">The new enumerable reference.</param>
private void OnItemsChanged ( IEnumerable newValue )
private void OnItemsChanged ( IEnumerable ? newValue )
{
// Remove handler for oldValue.CollectionChanged (if present)
_ collectionChangeSubscription ? . Dispose ( ) ;
@ -2198,28 +2199,28 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="sender">The object that raised the event.</param>
/// <param name="e">The event data.</param>
private void ItemsCollectionChanged ( object sender , NotifyCollectionChangedEventArgs e )
private void ItemsCollectionChanged ( object? sender , NotifyCollectionChangedEventArgs e )
{
// Update the cache
if ( e . Action = = NotifyCollectionChangedAction . Remove & & e . OldItems ! = null )
{
for ( int index = 0 ; index < e . OldItems . Count ; index + + )
{
_ items . RemoveAt ( e . OldStartingIndex ) ;
_ items ! . RemoveAt ( e . OldStartingIndex ) ;
}
}
if ( e . Action = = NotifyCollectionChangedAction . Add & & e . NewItems ! = null & & _ items . Count > = e . NewStartingIndex )
if ( e . Action = = NotifyCollectionChangedAction . Add & & e . NewItems ! = null & & _ items ! . Count > = e . NewStartingIndex )
{
for ( int index = 0 ; index < e . NewItems . Count ; index + + )
{
_ items . Insert ( e . NewStartingIndex + index , e . NewItems [ index ] ) ;
_ items . Insert ( e . NewStartingIndex + index , e . NewItems [ index ] ! ) ;
}
}
if ( e . Action = = NotifyCollectionChangedAction . Replace & & e . NewItems ! = null & & e . OldItems ! = null )
{
for ( int index = 0 ; index < e . NewItems . Count ; index + + )
{
_ items [ e . NewStartingIndex ] = e . NewItems [ index ] ;
_ items ! [ e . NewStartingIndex ] = e . NewItems [ index ] ! ;
}
}
@ -2228,7 +2229,7 @@ namespace Avalonia.Controls
{
for ( int index = 0 ; index < e . OldItems . Count ; index + + )
{
_ view . Remove ( e . OldItems [ index ] ) ;
_ view ! . Remove ( e . OldItems [ index ] ! ) ;
}
}
@ -2270,7 +2271,7 @@ namespace Avalonia.Controls
RefreshView ( ) ;
// Fire the Populated event containing the read-only view data.
PopulatedEventArgs populated = new PopulatedEventArgs ( new ReadOnlyCollection < object > ( _ view ) ) ;
PopulatedEventArgs populated = new PopulatedEventArgs ( new ReadOnlyCollection < object > ( _ view ! ) ) ;
OnPopulated ( populated ) ;
if ( SelectionAdapter ! = null & & SelectionAdapter . Items ! = _ view )
@ -2278,7 +2279,7 @@ namespace Avalonia.Controls
SelectionAdapter . Items = _ view ;
}
bool isDropDownOpen = _ userCalledPopulate & & ( _ view . Count > 0 ) ;
bool isDropDownOpen = _ userCalledPopulate & & ( _ view ! . Count > 0 ) ;
if ( isDropDownOpen ! = IsDropDownOpen )
{
_ ignorePropertyChange = true ;
@ -2306,20 +2307,20 @@ namespace Avalonia.Controls
private void UpdateTextCompletion ( bool userInitiated )
{
// By default this method will clear the selected value
object newSelectedItem = null ;
string text = Text ;
object? newSelectedItem = null ;
string? text = Text ;
// Text search is StartsWith explicit and only when enabled, in
// 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
// only valid when there is data and the user initiated the action.
if ( _ view . Count > 0 )
if ( _ view ! . Count > 0 )
{
if ( IsTextCompletionEnabled & & TextBox ! = null & & userInitiated )
{
int currentLength = TextBox . Text ? . Length ? ? 0 ;
int selectionStart = TextBoxSelectionStart ;
if ( selectionStart = = text . Length & & selectionStart > _ textSelectionStart )
if ( selectionStart = = text ? . Length & & selectionStart > _ textSelectionStart )
{
// When the FilterMode dependency property is set to
// either StartsWith or StartsWithCaseSensitive, the
@ -2327,7 +2328,7 @@ namespace Avalonia.Controls
// performance on the lookup. It assumes that the
// FilterMode the user has selected is an acceptable
// 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 ]
: TryGetMatch ( text , _ view , AutoCompleteSearch . GetFilter ( AutoCompleteFilterMode . StartsWith ) ) ;
@ -2335,18 +2336,18 @@ namespace Avalonia.Controls
if ( top ! = null )
{
newSelectedItem = top ;
string topString = FormatValue ( top , true ) ;
string? topString = FormatValue ( top , true ) ;
// Only replace partially when the two words being the same
int minLength = Math . Min ( topString . Length , Text . Length ) ;
if ( AutoCompleteSearch . Equals ( Text . Substring ( 0 , minLength ) , topString . Substring ( 0 , minLength ) ) )
int minLength = Math . Min ( topString ? . Length ? ? 0 , Text ? . Length ? ? 0 ) ;
if ( AutoCompleteSearch . Equals ( Text ? . Substring ( 0 , minLength ) , topString ? . Substring ( 0 , minLength ) ) )
{
// Update the text
UpdateTextValue ( topString ) ;
// Select the text past the user's caret
TextBox . SelectionStart = currentLength ;
TextBox . SelectionEnd = topString . Length ;
TextBox . SelectionEnd = topString ? . Length ? ? 0 ;
}
}
}
@ -2392,8 +2393,11 @@ namespace Avalonia.Controls
/// <param name="predicate">The predicate to use for the partial or
/// exact match.</param>
/// <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 )
{
if ( predicate is null )
return null ;
if ( view ! = null & & view . Count > 0 )
{
foreach ( object o in view )
@ -2428,9 +2432,9 @@ namespace Avalonia.Controls
/// that is displayed in the text box part.
/// </summary>
/// <param name="newItem">The new item.</param>
private void OnSelectedItemChanged ( object newItem )
private void OnSelectedItemChanged ( object? newItem )
{
string text ;
string? text ;
if ( newItem = = null )
{
@ -2461,9 +2465,9 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="sender">The source object.</param>
/// <param name="e">The selection changed event data.</param>
private void OnAdapterSelectionChanged ( object sender , SelectionChangedEventArgs e )
private void OnAdapterSelectionChanged ( object? sender , SelectionChangedEventArgs e )
{
SelectedItem = _ adapter . SelectedItem ;
SelectedItem = _ adapter ! . SelectedItem ;
}
//TODO Check UpdateTextCompletion
@ -2472,7 +2476,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="sender">The source object.</param>
/// <param name="e">The event data.</param>
private void OnAdapterSelectionComplete ( object sender , RoutedEventArgs e )
private void OnAdapterSelectionComplete ( object? sender , RoutedEventArgs e )
{
IsDropDownOpen = false ;
@ -2482,7 +2486,7 @@ namespace Avalonia.Controls
// Text should not be selected
ClearTextBoxSelection ( ) ;
TextBox . Focus ( ) ;
TextBox ! . Focus ( ) ;
}
/// <summary>
@ -2490,7 +2494,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="sender">The source object.</param>
/// <param name="e">The event data.</param>
private void OnAdapterSelectionCanceled ( object sender , RoutedEventArgs e )
private void OnAdapterSelectionCanceled ( object? sender , RoutedEventArgs e )
{
UpdateTextValue ( SearchText ) ;
@ -2510,7 +2514,7 @@ namespace Avalonia.Controls
/// </summary>
/// <param name="FilterMode">The built-in search mode.</param>
/// <returns>Returns the string-based comparison function.</returns>
public static AutoCompleteFilterPredicate < string > GetFilter ( AutoCompleteFilterMode FilterMode )
public static AutoCompleteFilterPredicate < string? > ? GetFilter ( AutoCompleteFilterMode FilterMode )
{
switch ( FilterMode )
{
@ -2566,9 +2570,11 @@ namespace Avalonia.Controls
/// <param name="value">The string value to search for.</param>
/// <param name="comparison">The string comparison type.</param>
/// <returns>Returns true when the substring is found.</returns>
private static bool Contains ( string s , string value , StringComparison comparison )
private static bool Contains ( string? s , string? value , StringComparison comparison )
{
return s . IndexOf ( value , comparison ) > = 0 ;
if ( s is not null & & value is not null )
return s . IndexOf ( value , comparison ) > = 0 ;
return false ;
}
/// <summary>
@ -2577,9 +2583,11 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool StartsWith ( string text , string value )
public static bool StartsWith ( string? text , string? value )
{
return value . StartsWith ( text , StringComparison . CurrentCultureIgnoreCase ) ;
if ( value is not null & & text is not null )
return value . StartsWith ( text , StringComparison . CurrentCultureIgnoreCase ) ;
return false ;
}
/// <summary>
@ -2588,9 +2596,11 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool StartsWithCaseSensitive ( string text , string value )
public static bool StartsWithCaseSensitive ( string? text , string? value )
{
return value . StartsWith ( text , StringComparison . CurrentCulture ) ;
if ( value is not null & & text is not null )
return value . StartsWith ( text , StringComparison . CurrentCulture ) ;
return false ;
}
/// <summary>
@ -2599,9 +2609,11 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool StartsWithOrdinal ( string text , string value )
public static bool StartsWithOrdinal ( string? text , string? value )
{
return value . StartsWith ( text , StringComparison . OrdinalIgnoreCase ) ;
if ( value is not null & & text is not null )
return value . StartsWith ( text , StringComparison . OrdinalIgnoreCase ) ;
return false ;
}
/// <summary>
@ -2610,9 +2622,11 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool StartsWithOrdinalCaseSensitive ( string text , string value )
public static bool StartsWithOrdinalCaseSensitive ( string? text , string? value )
{
return value . StartsWith ( text , StringComparison . Ordinal ) ;
if ( value is not null & & text is not null )
return value . StartsWith ( text , StringComparison . Ordinal ) ;
return false ;
}
/// <summary>
@ -2622,7 +2636,7 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool Contains ( string text , string value )
public static bool Contains ( string? text , string? value )
{
return Contains ( value , text , StringComparison . CurrentCultureIgnoreCase ) ;
}
@ -2633,7 +2647,7 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool ContainsCaseSensitive ( string text , string value )
public static bool ContainsCaseSensitive ( string? text , string? value )
{
return Contains ( value , text , StringComparison . CurrentCulture ) ;
}
@ -2644,7 +2658,7 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool ContainsOrdinal ( string text , string value )
public static bool ContainsOrdinal ( string? text , string? value )
{
return Contains ( value , text , StringComparison . OrdinalIgnoreCase ) ;
}
@ -2655,7 +2669,7 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool ContainsOrdinalCaseSensitive ( string text , string value )
public static bool ContainsOrdinalCaseSensitive ( string? text , string? value )
{
return Contains ( value , text , StringComparison . Ordinal ) ;
}
@ -2666,9 +2680,9 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool Equals ( string text , string value )
public static bool Equals ( string? text , string? value )
{
return value . Equals ( text , StringComparison . CurrentCultureIgnoreCase ) ;
return string . Equals ( value , text , StringComparison . CurrentCultureIgnoreCase ) ;
}
/// <summary>
@ -2677,9 +2691,9 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool EqualsCaseSensitive ( string text , string value )
public static bool EqualsCaseSensitive ( string? text , string? value )
{
return value . Equals ( text , StringComparison . CurrentCulture ) ;
return string . Equals ( value , text , StringComparison . CurrentCulture ) ;
}
/// <summary>
@ -2688,9 +2702,9 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool EqualsOrdinal ( string text , string value )
public static bool EqualsOrdinal ( string? text , string? value )
{
return value . Equals ( text , StringComparison . OrdinalIgnoreCase ) ;
return string . Equals ( value , text , StringComparison . OrdinalIgnoreCase ) ;
}
/// <summary>
@ -2699,9 +2713,9 @@ namespace Avalonia.Controls
/// <param name="text">The AutoCompleteBox prefix text.</param>
/// <param name="value">The item's string value.</param>
/// <returns>Returns true if the condition is met.</returns>
public static bool EqualsOrdinalCaseSensitive ( string text , string value )
public static bool EqualsOrdinalCaseSensitive ( string? text , string? value )
{
return value . Equals ( text , StringComparison . Ordinal ) ;
return string . Equals ( value , text , StringComparison . Ordinal ) ;
}
}
@ -2715,7 +2729,7 @@ namespace Avalonia.Controls
/// <summary>
/// Gets or sets the string value binding used by the control.
/// </summary>
private IBinding _ binding ;
private IBinding ? _ binding ;
#region public T Value
@ -2739,13 +2753,14 @@ namespace Avalonia.Controls
/// <summary>
/// Gets or sets the value binding.
/// </summary>
public IBinding ValueBinding
public IBinding ? ValueBinding
{
get { return _ binding ; }
set
{
_ binding = value ;
AvaloniaObjectExtensions . Bind ( this , ValueProperty , value ) ;
if ( value is not null )
AvaloniaObjectExtensions . Bind ( this , ValueProperty , value ) ;
}
}
@ -2760,7 +2775,7 @@ namespace Avalonia.Controls
/// setting the initial binding to the provided parameter.
/// </summary>
/// <param name="binding">The initial string value binding.</param>
public BindingEvaluator ( IBinding binding )
public BindingEvaluator ( IBinding ? binding )
: this ( )
{
ValueBinding = binding ;
@ -2802,7 +2817,7 @@ namespace Avalonia.Controls
/// <param name="o">The object to use as the data context.</param>
/// <returns>Returns the evaluated T value of the bound dependency
/// property.</returns>
public T GetDynamicValue ( object o )
public T GetDynamicValue ( object? o )
{
DataContext = o ;
return Value ;