Skip to content

Commit

Permalink
Ensure binding list provides RefreshItem when a refresh change is rec…
Browse files Browse the repository at this point in the history
…eived (#678)

Binding List Refresh
  • Loading branch information
RolandPheasant authored Feb 24, 2023
1 parent 957135a commit 260c034
Show file tree
Hide file tree
Showing 10 changed files with 306 additions and 50 deletions.
29 changes: 25 additions & 4 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,24 @@ root = true
insert_final_newline = true
indent_style = space
indent_size = 4
dotnet_style_operator_placement_when_wrapping = beginning_of_line
tab_width = 4
end_of_line = crlf
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_prefer_is_null_check_over_reference_equality_method = true:suggestion
dotnet_style_prefer_auto_properties = true:suggestion
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_prefer_simplified_boolean_expressions = true:suggestion
dotnet_style_prefer_conditional_expression_over_assignment = true:silent
dotnet_style_prefer_conditional_expression_over_return = true:silent
dotnet_style_explicit_tuple_names = true:suggestion
dotnet_style_prefer_inferred_tuple_names = true:suggestion
dotnet_style_prefer_inferred_anonymous_type_member_names = true:suggestion
dotnet_style_prefer_compound_assignment = true:suggestion
dotnet_style_prefer_simplified_interpolation = true:suggestion
dotnet_style_namespace_match_folder = true:suggestion

[project.json]
indent_size = 2
Expand Down Expand Up @@ -54,15 +72,15 @@ dotnet_style_predefined_type_for_member_access = true:suggestion
# name all constant fields using PascalCase
dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
dotnet_naming_symbols.constant_fields.applicable_kinds = field
dotnet_naming_symbols.constant_fields.required_modifiers = const
dotnet_naming_style.pascal_case_style.capitalization = pascal_case

# static fields should have s_ prefix
dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
dotnet_naming_symbols.static_fields.applicable_kinds = field
dotnet_naming_symbols.static_fields.required_modifiers = static
dotnet_naming_symbols.static_fields.applicable_accessibilities = private, internal, private_protected
Expand All @@ -72,7 +90,7 @@ dotnet_naming_style.static_prefix_style.capitalization = camel_case
# internal and private fields should be _camelCase
dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
dotnet_naming_style.camel_case_underscore_style.required_prefix = _
Expand Down Expand Up @@ -470,7 +488,7 @@ dotnet_diagnostic.SA1200.severity = none

dotnet_diagnostic.SA1201.severity = none

dotnet_diagnostic.SA1202.severity = error
dotnet_diagnostic.SA1202.severity = silent

dotnet_diagnostic.SA1203.severity = error

Expand Down Expand Up @@ -676,6 +694,9 @@ dotnet_diagnostic.SX1309.severity = error

dotnet_diagnostic.SX1623.severity = none
dotnet_diagnostic.SX1309S.severity=silent
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent

# C++ Files
[*.{cpp,h,in}]
Expand Down
45 changes: 24 additions & 21 deletions src/Directory.build.targets
Original file line number Diff line number Diff line change
@@ -1,30 +1,33 @@
<Project>
<PropertyGroup>
<Product>$(AssemblyName) ($(TargetFramework))</Product>
</PropertyGroup>
<PropertyGroup>
<Product>$(AssemblyName) ($(TargetFramework))</Product>
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework.StartsWith('uap'))">
<DefineConstants>$(DefineConstants);WINDOWS_UWP;P_LINQ</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('uap'))">
<DefineConstants>$(DefineConstants);WINDOWS_UWP;P_LINQ</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework.StartsWith('net4'))">
<DefineConstants>$(DefineConstants);P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('net4'))">
<DefineConstants>$(DefineConstants);P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework.StartsWith('netstandard'))">
<DefineConstants>$(DefineConstants);NETSTANDARD;PORTABLE;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('netstandard'))">
<DefineConstants>$(DefineConstants);NETSTANDARD;PORTABLE;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework.StartsWith('netcoreapp'))">
<DefineConstants>$(DefineConstants);NETCOREAPP;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('netcoreapp'))">
<DefineConstants>$(DefineConstants);NETCOREAPP;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework.StartsWith('net5'))">
<DefineConstants>$(DefineConstants);NETSTANDARD;PORTABLE;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('net5'))">
<DefineConstants>$(DefineConstants);NETSTANDARD;PORTABLE;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework.StartsWith('net6'))">
<DefineConstants>$(DefineConstants);NETSTANDARD;PORTABLE;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="$(TargetFramework.StartsWith('net6'))">
<DefineConstants>$(DefineConstants);NETSTANDARD;PORTABLE;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>

<PropertyGroup Condition="$(TargetFramework.StartsWith('net7'))">
<DefineConstants>$(DefineConstants);NETSTANDARD;PORTABLE;P_LINQ;SUPPORTS_BINDINGLIST</DefineConstants>
</PropertyGroup>
</Project>
37 changes: 32 additions & 5 deletions src/DynamicData.Tests/Binding/BindingLIstBindListFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ public BindingLIstBindListFixture()
{
_collection = new BindingList<Person>();
_source = new SourceList<Person>();
_binder = _source.Connect().Bind(_collection).Subscribe();
_binder = _source.Connect()
.AutoRefresh(p => p.Age)
.Bind(_collection)
.Subscribe();
}

[Fact]
Expand Down Expand Up @@ -58,12 +61,29 @@ public void Clear()
_collection.Count.Should().Be(0, "Should be 100 items in the collection");
}

public void Dispose()


[Fact]
public void Refresh()
{
_binder.Dispose();
_source.Dispose();
var people = _generator.Take(100).ToList();
_source.AddRange(people);

ListChangedEventArgs? args = null;

_collection.ListChanged += (_, e) =>
{
args = e;
};

people[10].Age = 100;

args.Should().NotBeNull();
args.ListChangedType.Should().Be(ListChangedType.ItemChanged);
args.NewIndex.Should().Be(10);
}


[Fact]
public void RemoveSourceRemovesFromTheDestination()
{
Expand All @@ -85,6 +105,13 @@ public void UpdateToSourceUpdatesTheDestination()
_collection.Count.Should().Be(1, "Should be 1 item in the collection");
_collection.First().Should().Be(personUpdated, "Should be updated person");
}

public void Dispose()
{
_binder.Dispose();
_source.Dispose();
}

}
}
#endif
#endif
33 changes: 27 additions & 6 deletions src/DynamicData.Tests/Binding/BindingListBindCacheFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,6 @@ public void BatchRemove()
_collection.Count.Should().Be(0, "Should be 100 items in the collection");
}

public void Dispose()
{
_binder.Dispose();
_source.Dispose();
}

[Fact]
public void RemoveSourceRemovesFromTheDestination()
Expand All @@ -73,6 +68,26 @@ public void RemoveSourceRemovesFromTheDestination()
_collection.Count.Should().Be(0, "Should be 1 item in the collection");
}

[Fact]
public void Refresh()
{
var people = _generator.Take(100).ToList();
_source.AddOrUpdate(people);

ListChangedEventArgs? args = null;

_collection.ListChanged += (_, e) =>
{
args = e;
};

_source.Refresh(people[10]);

args.Should().NotBeNull();
args.ListChangedType.Should().Be(ListChangedType.ItemChanged);
args.NewIndex.Should().Be(10);
}

[Fact]
public void UpdateToSourceUpdatesTheDestination()
{
Expand All @@ -84,6 +99,12 @@ public void UpdateToSourceUpdatesTheDestination()
_collection.Count.Should().Be(1, "Should be 1 item in the collection");
_collection.First().Should().Be(personUpdated, "Should be updated person");
}

public void Dispose()
{
_binder.Dispose();
_source.Dispose();
}
}
}
#endif
#endif
38 changes: 32 additions & 6 deletions src/DynamicData.Tests/Binding/BindingListBindCacheSortedFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,6 @@ public void CollectionIsInSortOrder()
sorted.Should().BeEquivalentTo(_collection.ToList());
}

public void Dispose()
{
_binder.Dispose();
_source.Dispose();
}

[Fact]
public void LargeUpdateInvokesAReset()
Expand All @@ -93,6 +88,28 @@ public void LargeUpdateInvokesAReset()
invoked.Should().BeTrue();
}

[Fact]
public void Refresh()
{
var people = _generator.Take(100).ToList();
_source.AddOrUpdate(people);

ListChangedEventArgs? args = null;

_collection.ListChanged += (_, e) =>
{
args = e;
};

_source.Refresh(people[10]);

args.Should().NotBeNull();
args.ListChangedType.Should().Be(ListChangedType.ItemChanged);

_collection[args.NewIndex].Should().Be(people[10]);
}


[Fact]
public void RemoveSourceRemovesFromTheDestination()
{
Expand Down Expand Up @@ -179,6 +196,15 @@ public void UpdateToSourceUpdatesTheDestination()
_collection.Count.Should().Be(1, "Should be 1 item in the collection");
_collection.First().Should().Be(personUpdated, "Should be updated person");
}


public void Dispose()
{
_binder.Dispose();
_source.Dispose();
}
}


}
#endif
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,12 @@ public void RefreshCausesReplace()
sourceCacheResults.Messages.First().Adds.Should().Be(1);
sourceCacheResults.Messages.Last().Refreshes.Should().Be(1);

// List receives add and replace instead of refresh
collectionResults.Messages.Count.Should().Be(2);

/*
List receives add and replace instead of refresh (and as of 23/02/2023 it receives a refresh too!)
*/

collectionResults.Messages.Count.Should().Be(3);
collectionResults.Messages.First().Adds.Should().Be(1);
collectionResults.Messages.First().Refreshes.Should().Be(0);
collectionResults.Messages.Last().Replaced.Should().Be(1);
Expand Down
11 changes: 9 additions & 2 deletions src/DynamicData/Binding/BindingListAdaptor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
// See the LICENSE file in the project root for full license information.

#if SUPPORTS_BINDINGLIST
using System;
using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;

Expand Down Expand Up @@ -129,10 +128,18 @@ private static void DoUpdate(IChangeSet<TObject, TKey> changes, BindingList<TObj

list.Add(update.Current);
break;

case ChangeReason.Refresh:
{
var index = list.IndexOf(update.Current);
if (index != -1)
list.ResetItem(index);
break;
}
}
}
}
}
}

#endif
#endif
Loading

0 comments on commit 260c034

Please sign in to comment.