Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/Common/tests/CommonTestHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,22 @@ public static TheoryData<Color> GetColorWithEmptyTheoryData()
return data;
}

public static TheoryData<Image> GetImageTheoryData()
{
var data = new TheoryData<Image>();
data.Add(new Bitmap(10, 10));
data.Add(null);
return data;
}

public static TheoryData<Font> GetFontTheoryData()
{
var data = new TheoryData<Font>();
data.Add(SystemFonts.MenuFont);
data.Add(null);
return data;
}

public static TheoryData<Type> GetTypeWithNullTheoryData()
{
var data = new TheoryData<Type>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2094,9 +2094,6 @@ protected void UseStdAccessibleObjects(IntPtr handle, int objid)
ref IID_IEnumVariant,
ref en);

Debug.Assert(acc != null, "SystemIAccessible is null");
Debug.Assert(en != null, "SystemIEnumVariant is null");

if (acc != null || en != null)
{
systemIAccessible = (IAccessible)acc;
Expand Down
79 changes: 23 additions & 56 deletions src/System.Windows.Forms/src/System/Windows/Forms/ComboBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2001,79 +2001,46 @@ public void EndUpdate() {
}
}

/// <include file='doc\ComboBox.uex' path='docs/doc[@for="ComboBox.FindString"]/*' />
/// <devdoc>
/// Finds the first item in the combo box that starts with the given string.
/// The search is not case sensitive.
/// Finds the first item in the combo box that starts with the given string.
/// The search is not case sensitive.
/// </devdoc>
public int FindString(string s) {
return FindString(s, -1);
}
public int FindString(string s) => FindString(s, startIndex: -1);

/// <include file='doc\ComboBox.uex' path='docs/doc[@for="ComboBox.FindString1"]/*' />
/// <devdoc>
/// Finds the first item after the given index which starts with the given
/// string. The search is not case sensitive.
/// Finds the first item after the given index which starts with the given string.
/// The search is not case sensitive.
/// </devdoc>
public int FindString(string s, int startIndex) {
if (s == null) {
return -1;
}

if (itemsCollection == null || itemsCollection.Count == 0) {
return -1;
}

// The last item in the list is still a valid starting point for a search.
if (startIndex < -1 || startIndex >= itemsCollection.Count) {
throw new ArgumentOutOfRangeException(nameof(startIndex));
}

// Always use the managed FindStringInternal instead of CB_FINDSTRING.
// The managed version correctly handles Turkish I.
return FindStringInternal(s, Items, startIndex, exact: false, ignoreCase: true);
public int FindString(string s, int startIndex)
{
return FindStringInternal(s, itemsCollection, startIndex, exact: false, ignoreCase: true);
}

/// <include file='doc\ComboBox.uex' path='docs/doc[@for="ComboBox.FindStringExact"]/*' />
/// <devdoc>
/// Finds the first item in the combo box that matches the given string.
/// The strings must match exactly, except for differences in casing.
/// Finds the first item in the combo box that matches the given string.
/// The strings must match exactly, except for differences in casing.
/// </devdoc>
public int FindStringExact(string s) {
return FindStringExact(s, -1, true);
public int FindStringExact(string s)
{
return FindStringExact(s, startIndex: -1, ignoreCase: true);
}

/// <include file='doc\ComboBox.uex' path='docs/doc[@for="ComboBox.FindStringExact1"]/*' />
/// <devdoc>
/// Finds the first item after the given index that matches the given
/// string. The strings must match exactly, except for differences in
/// casing.
/// Finds the first item after the given index that matches the given string.
/// The strings must match exactly, except for differences in casing.
/// </devdoc>
public int FindStringExact(string s, int startIndex) {
return FindStringExact(s, startIndex, true);
public int FindStringExact(string s, int startIndex)
{
return FindStringExact(s, startIndex, ignoreCase: true);
}

/// <include file='doc\ComboBox.uex' path='docs/doc[@for="ComboBox.FindStringExact1"]/*' />
/// <devdoc>
/// Finds the first item after the given index that matches the given
/// string. The strings must match exactly, except for differences in
/// casing.
/// Finds the first item after the given index that matches the given string.
/// The strings must match exactly, except for differences in casing.
/// </devdoc>
internal int FindStringExact(string s, int startIndex, bool ignoreCase) {
if (s == null) return -1;

if (itemsCollection == null || itemsCollection.Count == 0) {
return -1;
}

// The last item in the list is still a valid starting point for a search.
if (startIndex < -1 || startIndex >= itemsCollection.Count) {
throw new ArgumentOutOfRangeException(nameof(startIndex));
}

// Always use the managed FindStringInternal instead of CB_FINDSTRINGEXACT.
// The managed version correctly handles Turkish I.
return FindStringInternal(s, Items, startIndex, exact: true, ignoreCase);
internal int FindStringExact(string s, int startIndex, bool ignoreCase)
{
return FindStringInternal(s, itemsCollection, startIndex, exact: true, ignoreCase);
}

// GetPreferredSize and SetBoundsCore call this method to allow controls to self impose
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3649,7 +3649,7 @@ public virtual RightToLeft RightToLeft {
set {
//valid values are 0x0 to 0x2.
if (!ClientUtils.IsEnumValid(value, (int)value, (int)RightToLeft.No, (int)RightToLeft.Inherit)){
throw new InvalidEnumArgumentException(nameof(RightToLeft), (int)value, typeof(RightToLeft));
throw new InvalidEnumArgumentException(nameof(value), (int)value, typeof(RightToLeft));
}

RightToLeft oldValue = RightToLeft;
Expand Down
69 changes: 16 additions & 53 deletions src/System.Windows.Forms/src/System/Windows/Forms/ListBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1365,71 +1365,34 @@ public void EndUpdate() {
--updateCount;
}

/// <include file='doc\ListBox.uex' path='docs/doc[@for="ListBox.FindString"]/*' />
/// <devdoc>
/// Finds the first item in the list box that starts with the given string.
/// The search is not case sensitive.
/// Finds the first item in the list box that starts with the given string.
/// The search is not case sensitive.
/// </devdoc>
public int FindString(string s) {
return FindString(s, -1);
}
public int FindString(string s) => FindString(s, startIndex: -1);

/// <include file='doc\ListBox.uex' path='docs/doc[@for="ListBox.FindString1"]/*' />
/// <devdoc>
/// Finds the first item after the given index which starts with the given
/// string. The search is not case sensitive.
/// Finds the first item after the given index which starts with the given string.
/// The search is not case sensitive.
/// </devdoc>
public int FindString(string s, int startIndex) {
if (s == null) return -1;

int itemCount = (itemsCollection == null) ? 0 : itemsCollection.Count;

if (itemCount == 0) {
return -1;
}

// The last item in the list is still a valid starting point for a search.
if (startIndex < -1 || startIndex >= itemCount) {
throw new ArgumentOutOfRangeException(nameof(startIndex));
}

// Always use the managed FindStringInternal instead of LB_FINDSTRING.
// The managed version correctly handles Turkish I.
return FindStringInternal(s, Items, startIndex, exact: false, ignoreCase: true);
public int FindString(string s, int startIndex)
{
return FindStringInternal(s, itemsCollection, startIndex, exact: false, ignoreCase: true);
}

/// <include file='doc\ListBox.uex' path='docs/doc[@for="ListBox.FindStringExact"]/*' />
/// <devdoc>
/// Finds the first item in the list box that matches the given string.
/// The strings must match exactly, except for differences in casing.
/// Finds the first item in the list box that matches the given string.
/// The strings must match exactly, except for differences in casing.
/// </devdoc>
public int FindStringExact(string s) {
return FindStringExact(s, -1);
}
public int FindStringExact(string s) => FindStringExact(s, startIndex: -1);

/// <include file='doc\ListBox.uex' path='docs/doc[@for="ListBox.FindStringExact1"]/*' />
/// <devdoc>
/// Finds the first item after the given index that matches the given
/// string. The strings must match excatly, except for differences in
/// casing.
/// Finds the first item after the given index that matches the given string.
/// The strings must match excatly, except for differences in casing.
/// </devdoc>
public int FindStringExact(string s, int startIndex) {
if (s == null) return -1;

int itemCount = (itemsCollection == null) ? 0 : itemsCollection.Count;

if (itemCount == 0) {
return -1;
}

// The last item in the list is still a valid starting point for a search.
if (startIndex < -1 || startIndex >= itemCount) {
throw new ArgumentOutOfRangeException(nameof(startIndex));
}

// Always use the managed FindStringInternal instead of LB_FINDSTRING.
// The managed version correctly handles Turkish I.
return FindStringInternal(s, Items, startIndex, exact: true, ignoreCase: true);
public int FindStringExact(string s, int startIndex)
{
return FindStringInternal(s, itemsCollection, startIndex, exact: true, ignoreCase: true);
}

/// <include file='doc\ListBox.uex' path='docs/doc[@for="ListBox.GetItemHeight"]/*' />
Expand Down
56 changes: 21 additions & 35 deletions src/System.Windows.Forms/src/System/Windows/Forms/ListControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public object DataSource
{
if (value != null && !(value is IList || value is IListSource))
{
throw new ArgumentException(SR.BadDataSourceForComplexBinding);
throw new ArgumentException(SR.BadDataSourceForComplexBinding, nameof(value));
}

if (_dataSource == value)
Expand Down Expand Up @@ -150,11 +150,9 @@ private TypeConverter DisplayMemberConverter
{
get
{
if (_displayMemberConverter == null &&
DataManager != null &&
_displayMember != null)
if (_displayMemberConverter == null)
{
PropertyDescriptorCollection props = DataManager.GetItemProperties();
PropertyDescriptorCollection props = DataManager?.GetItemProperties();
if (props != null)
{
PropertyDescriptor displayMemberProperty = props.Find(_displayMember.BindingField, true);
Expand Down Expand Up @@ -285,17 +283,13 @@ public event EventHandler FormattingEnabledChanged
}
}

private bool BindingMemberInfoInDataManager(BindingMemberInfo bindingMemberInfo)
private static bool BindingMemberInfoInDataManager(CurrencyManager dataManager, BindingMemberInfo bindingMemberInfo)
{
if (_dataManager == null)
{
return false;
}
Debug.Assert(dataManager != null);

PropertyDescriptorCollection props = _dataManager.GetItemProperties();
int propsCount = props.Count;
PropertyDescriptorCollection props = dataManager.GetItemProperties();

for (int i = 0; i < propsCount; i++)
for (int i = 0; i < props.Count; i++)
{
if (typeof(IList).IsAssignableFrom(props[i].PropertyType))
{
Expand All @@ -307,7 +301,7 @@ private bool BindingMemberInfoInDataManager(BindingMemberInfo bindingMemberInfo)
}
}

for (int i = 0; i < propsCount; i++)
for (int i = 0; i < props.Count; i++)
{
if (typeof(IList).IsAssignableFrom(props[i].PropertyType))
{
Expand Down Expand Up @@ -350,7 +344,7 @@ public string ValueMember
// the properties in the dataManager
if (DataManager != null && !string.IsNullOrEmpty(value))
{
if (!BindingMemberInfoInDataManager(newValueMember))
if (!BindingMemberInfoInDataManager(DataManager, newValueMember))
{
throw new ArgumentException(SR.ListControlWrongValueMember, nameof(value));
}
Expand Down Expand Up @@ -474,7 +468,7 @@ protected object FilterItemOnProperty(object item)

protected object FilterItemOnProperty(object item, string field)
{
if (item != null && field.Length > 0)
if (item != null && !string.IsNullOrEmpty(field))
{
try
{
Expand Down Expand Up @@ -509,19 +503,18 @@ protected object FilterItemOnProperty(object item, string field)

private protected int FindStringInternal(string str, IList items, int startIndex, bool exact, bool ignoreCase)
{
if (str == null || items == null)
if (str == null)
{
return -1;
}

// The last item in the list is still a valid place to start looking.
if (startIndex < -1 || startIndex >= items.Count)
if (items == null || items.Count == 0)
{
return -1;
}

bool found = false;
int length = str.Length;
if (startIndex < -1 || startIndex >= items.Count)
{
throw new ArgumentOutOfRangeException(nameof(startIndex));
}

// Start from the start index and wrap around until we find the string
// in question. Use a separate counter to ensure that we arent cycling through the list infinitely.
Expand All @@ -531,13 +524,15 @@ private protected int FindStringInternal(string str, IList items, int startIndex
for (int index = (startIndex + 1) % items.Count; numberOfTimesThroughLoop < items.Count; index = (index + 1) % items.Count)
{
numberOfTimesThroughLoop++;

bool found;
if (exact)
{
found = string.Compare(str, GetItemText(items[index]), ignoreCase, CultureInfo.CurrentCulture) == 0;
}
else
{
found = string.Compare(str, 0, GetItemText(items[index]), 0, length, ignoreCase, CultureInfo.CurrentCulture) == 0;
found = string.Compare(str, 0, GetItemText(items[index]), 0, str.Length, ignoreCase, CultureInfo.CurrentCulture) == 0;
}

if (found)
Expand Down Expand Up @@ -588,11 +583,6 @@ public string GetItemText(object item)
}
catch (Exception exception) when (!ClientUtils.IsSecurityOrCriticalException(exception))
{
if (filteredItem == null)
{
return string.Empty;
}

// if we did not do any work then return the old ItemText
return Convert.ToString(item, CultureInfo.CurrentCulture);
}
Expand Down Expand Up @@ -671,7 +661,7 @@ protected virtual void OnFormattingEnabledChanged(EventArgs e)
/// </devdoc>
protected virtual void OnSelectedIndexChanged(EventArgs e)
{
OnSelectedValueChanged(EventArgs.Empty);
OnSelectedValueChanged(e);
}

protected virtual void OnValueMemberChanged(EventArgs e)
Expand All @@ -694,15 +684,11 @@ protected virtual void RefreshItems()

private void DataSourceDisposed(object sender, EventArgs e)
{
Debug.Assert(sender == _dataSource, "how can we get dispose notification for anything other than our dataSource?");
SetDataConnection(null, new BindingMemberInfo(string.Empty), true);
}

private void DataSourceInitialized(object sender, EventArgs e)
{
ISupportInitializeNotification dsInit = (_dataSource as ISupportInitializeNotification);
Debug.Assert(dsInit != null, "ListControl: ISupportInitializeNotification.Initialized event received, but current DataSource does not support ISupportInitializeNotification!");
Debug.Assert(dsInit.IsInitialized, "ListControl: DataSource sent ISupportInitializeNotification.Initialized event but before it had finished initializing.");
SetDataConnection(_dataSource, _displayMember, true);
}

Expand Down Expand Up @@ -763,7 +749,7 @@ private void SetDataConnection(object newDataSource, BindingMemberInfo newDispla
// "" is a good value for displayMember
if (_dataManager != null && (displayMemberChanged || dataSourceChanged) && !string.IsNullOrEmpty(_displayMember.BindingMember))
{
if (!BindingMemberInfoInDataManager(_displayMember))
if (!BindingMemberInfoInDataManager(_dataManager, _displayMember))
{
throw new ArgumentException(SR.ListControlWrongDisplayMember, nameof(newDisplayMember));
}
Expand Down
Loading