Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for Selector.SelectionChanged is raised twice on updated selection #547

Merged
merged 4 commits into from
Feb 1, 2019
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
1 change: 1 addition & 0 deletions doc/ReleaseNotes/_ReleaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
* Ensure that Uno.UI can be used with VS15.8 and earlier (prevent the use of VS15.9 and later String APIs)
* [Android] Listview Items stay visually in a pressed state,(can click multiple) when you click then scroll down, click another item, and scroll back up
* 144101 fixed `ListView` group headers messed up on item update
* #527 Fix for `Selector.SelectionChanged` is raised twice on updated selection

## Release 1.42

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,12 +141,12 @@ private static string RemoveWrappingStringQuotes(string stringValue)
// Remove wrapping single quotes.
if (stringValue.StartsWith("'") && stringValue.EndsWith("'"))
{
return stringValue.Trim('\'');
return stringValue.Trim(new[] { '\'' });
}
// Remove wrapping double quotes.
else if (stringValue.StartsWith("\"") && stringValue.EndsWith("\""))
{
return stringValue.Trim('\"');
return stringValue.Trim(new[] { '\"' });
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Uno.Foundation/Uno.Foundation.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</ItemGroup>

<ItemGroup>
<Analyzer Include="..\Uno.MonoAnalyzers\bin\$(Configuration)\net46\Uno.MonoAnalyzers.dll" />
<Analyzer Include="$(MSBuildThisFileDirectory)..\Uno.MonoAnalyzers\bin\$(Configuration)\net46\Uno.MonoAnalyzers.dll" />
</ItemGroup>

<ItemGroup>
Expand Down
1 change: 1 addition & 0 deletions src/Uno.MonoAnalyzers/MonoNotSupportedAPIAnalyzer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ public Container(Compilation compilation, MonoNotSupportedAPIAnalyzer owner)
"Split",
"TrimStart",
"TrimEnd",
"Trim",
"IndexOfAny",
"Join",
"StartsWith",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,17 @@
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;

namespace Uno.UI.Tests.ListViewBaseTests
{
[TestClass]
public class Given_ListViewBase
{

[TestMethod]
public void When_SingleSelectedItem()
public void When_MultiSelectedItem()
{
var style = new Style(typeof(Windows.UI.Xaml.Controls.ListViewBase))
{
Expand All @@ -36,22 +38,29 @@ public void When_SingleSelectedItem()
Style = style,
ItemsPanel = new ItemsPanelTemplate(() => panel),
Items = {
new Border { Name = "b1" }
new Border { Name = "b1" },
new Border { Name = "b2" }
}
};

// Search on the panel for now, as the name lookup is not properly
// aligned on net46.
Assert.IsNotNull(panel.FindName("b1"));
Assert.IsNotNull(panel.FindName("b2"));

SUT.SelectedIndex = 0;
SUT.SelectionMode = ListViewSelectionMode.Multiple;

SUT.OnItemClicked(0);

Assert.IsNotNull(SUT.SelectedItem);
Assert.AreEqual(1, SUT.SelectedItems.Count);

SUT.OnItemClicked(1);

Assert.AreEqual(2, SUT.SelectedItems.Count);
}

[TestMethod]
public void When_MultiSelectedItem()
public void When_SingleSelectedItem_Event()
{
var style = new Style(typeof(Windows.UI.Xaml.Controls.ListViewBase))
{
Expand All @@ -66,32 +75,89 @@ public void When_MultiSelectedItem()

var panel = new StackPanel();

var item = new Border { Name = "b1" };
var SUT = new ListViewBase()
{
Style = style,
ItemsPanel = new ItemsPanelTemplate(() => panel),
Items = {
new Border { Name = "b1" },
new Border { Name = "b2" }
item
}
};

var model = new MyModel
{
SelectedItem = (object)null
};

SUT.SetBinding(
Selector.SelectedItemProperty,
new Binding()
{
Path = "SelectedItem",
Source = model,
Mode = BindingMode.TwoWay
}
);

// Search on the panel for now, as the name lookup is not properly
// aligned on net46.
Assert.IsNotNull(panel.FindName("b1"));
Assert.IsNotNull(panel.FindName("b2"));

SUT.SelectionMode = ListViewSelectionMode.Multiple;
var selectionChanged = 0;

SUT.OnItemClicked(0);
SUT.SelectionChanged += (s, e) =>
{
selectionChanged++;
Assert.AreEqual(item, SUT.SelectedItem);

// In windows, when programmatically changed, the bindings are updated *after*
// the event is raised, but *before* when the SelectedItem is changed from the UI.
Assert.IsNull(model.SelectedItem);
};

SUT.SelectedIndex = 0;

Assert.AreEqual(item, model.SelectedItem);

Assert.IsNotNull(SUT.SelectedItem);
Assert.AreEqual(1, selectionChanged);
Assert.AreEqual(1, SUT.SelectedItems.Count);
}

SUT.OnItemClicked(1);
[TestMethod]
public void When_ResetItemsSource()
{
var style = new Style(typeof(Windows.UI.Xaml.Controls.ListViewBase))
{
Setters = {
new Setter<ItemsControl>("Template", t =>
t.Template = Funcs.Create(() =>
new ItemsPresenter()
)
)
}
};

Assert.AreEqual(2, SUT.SelectedItems.Count);
var panel = new StackPanel();

var SUT = new ListViewBase()
{
Style = style,
ItemsPanel = new ItemsPanelTemplate(() => panel),
SelectionMode = ListViewSelectionMode.Single,
};

SUT.ItemsSource = new int[] { 1, 2, 3 };
SUT.OnItemClicked(0);

SUT.ItemsSource = null;
}
}

public class MyModel
{
public object SelectedItem { get; set; }
}

public class MyItemsControl : ItemsControl
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UI.Toolkit/Uno.UI.Toolkit.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@
<Target Name="Publish" />

<ItemGroup>
<Analyzer Include="..\Uno.MonoAnalyzers\bin\$(Configuration)\net46\Uno.MonoAnalyzers.dll" />
<Analyzer Include="$(MSBuildThisFileDirectory)..\Uno.MonoAnalyzers\bin\$(Configuration)\net46\Uno.MonoAnalyzers.dll" />
</ItemGroup>

<PropertyGroup>
Expand Down
21 changes: 18 additions & 3 deletions src/Uno.UI/UI/Xaml/Controls/ListViewBase/ListViewBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,25 @@ internal override void OnSelectedItemChanged(object oldSelectedItem, object sele
}
else
{
SelectedItems.Clear();
SelectedItems.Add(selectedItem);

base.OnSelectedItemChanged(oldSelectedItem, selectedItem);

try
{
_modifyingSelectionInternally = true;

if (selectedItem != null)
{
SelectedItems.Update(new[] { selectedItem });
}
else
{
SelectedItems.Clear();
}
}
finally
{
_modifyingSelectionInternally = false;
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/Uno.UI/Uno.UI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@
</ItemGroup>

<PropertyGroup>
<UnoUIGeneratorsBinPath>..\SourceGenerators\Uno.UI.SourceGenerators\bin\$(Configuration)</UnoUIGeneratorsBinPath>
<UnoUIGeneratorsBinPath>$(MSBuildThisFileDirectory)..\SourceGenerators\Uno.UI.SourceGenerators\bin\$(Configuration)</UnoUIGeneratorsBinPath>
<UnoUIMSBuildTasksPath>$(MSBuildThisFileDirectory)..\SourceGenerators\Uno.UI.Tasks\bin\$(Configuration)_Shadow</UnoUIMSBuildTasksPath>
</PropertyGroup>

Expand All @@ -327,7 +327,7 @@
</ItemGroup>

<ItemGroup>
<Analyzer Include="..\Uno.MonoAnalyzers\bin\$(Configuration)\net46\Uno.MonoAnalyzers.dll" />
<Analyzer Include="$(MSBuildThisFileDirectory)..\Uno.MonoAnalyzers\bin\$(Configuration)\net46\Uno.MonoAnalyzers.dll" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Uno.UWP/Uno.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
</ItemGroup>

<ItemGroup>
<Analyzer Include="..\Uno.MonoAnalyzers\bin\$(Configuration)\net46\Uno.MonoAnalyzers.dll" />
<Analyzer Include="$(MSBuildThisFileDirectory)..\Uno.MonoAnalyzers\bin\$(Configuration)\net46\Uno.MonoAnalyzers.dll" />
</ItemGroup>

<ItemGroup>
Expand Down