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

SaveDropDownSelectedItem #9367

Merged
merged 8 commits into from
Jan 8, 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
56 changes: 46 additions & 10 deletions src/Libraries/CoreNodeModels/DropDown.cs
Original file line number Diff line number Diff line change
Expand Up @@ -71,24 +71,59 @@ public override NodeInputData InputData
get { return null; }
}

private int selectedIndex = 0;
private int selectedIndex = -1;

/// <summary>
/// Index of current selection
/// </summary>
public int SelectedIndex
{
get { return selectedIndex; }
set
{
//do not allow selected index to
//go out of range of the items collection
if (value > Items.Count - 1)
if (value > Items.Count - 1 || value == -1)
{
selectedIndex = -1;
selectedString = String.Empty;
}
else
{
selectedIndex = value;
selectedString = Items.ElementAt(value).Item.ToString();
}
RaisePropertyChanged("SelectedIndex");
}
}

private string selectedString = String.Empty;

/// <summary>
/// String form of current selected item, so derived class
/// can save customized data
/// </summary>
public string SelectedString
{
get { return selectedString; }
set
{
if (!string.IsNullOrEmpty(value) && value != selectedString)
{
var item = Items.FirstOrDefault(i => i.Item.ToString().Equals(value));
// In the case that SelectedString deserialize after SelectedIndex
// With a valid item from search, get the index of item and replace the current one.
// If no exact match found, fall back to use the default selectedIndex from deserialization.
selectedIndex = item != null ?
Items.IndexOf(item) :
selectedIndex;
}

selectedString = value;
RaisePropertyChanged("SelectedString");
}
}

protected DSDropDownBase(string outputName)
{
OutPorts.Add(new PortModel(PortType.Output, this, new PortData(outputName, string.Format(Resources.DropDownPortDataResultToolTip, outputName))));
Expand All @@ -111,7 +146,7 @@ protected override void SerializeCore(XmlElement nodeElement, SaveContext contex
protected override void DeserializeCore(XmlElement nodeElement, SaveContext context)
{
base.DeserializeCore(nodeElement, context);
// Drop downs previsouly saved their selected index as an int.
// Drop downs previously saved their selected index as an int.
// Between versions of host applications where the number or order of items
// in a list would vary, this made loading of drop downs un-reliable.
// We have upgraded drop downs to save their selected index as
Expand All @@ -122,6 +157,7 @@ protected override void DeserializeCore(XmlElement nodeElement, SaveContext cont
return;

selectedIndex = ParseSelectedIndex(attrib.Value, Items);
selectedString = Items.ElementAt(selectedIndex).Item.ToString();

if (selectedIndex < 0)
{
Expand All @@ -139,6 +175,7 @@ protected override bool UpdateValueCore(UpdateValueParams updateValueParams)
selectedIndex = ParseSelectedIndex(value, Items);
if (selectedIndex < 0)
Warning(Dynamo.Properties.Resources.NothingIsSelectedWarning);
selectedString = Items.ElementAt(selectedIndex).Item.ToString();
return true; // UpdateValueCore handled.
}

Expand Down Expand Up @@ -210,20 +247,19 @@ protected static string XmlUnescape(string escaped)

public void PopulateItems()
{
var currentSelection = string.Empty;
if (SelectedIndex >= 0 && (SelectedIndex < items.Count))
{
currentSelection = items.ElementAt(SelectedIndex).Name;
}
var currentSelection = SelectedString;
var selectionState = PopulateItemsCore(currentSelection);
if (selectionState == SelectionState.Restore)

// Restore the selection when selectedIndex is valid
if (selectionState == SelectionState.Restore && !String.IsNullOrEmpty(currentSelection))
{
SelectedIndex = -1;
for (int i = 0; i < items.Count; i++)
{
if ((items.ElementAt(i)).Name.Equals(currentSelection))
{
SelectedIndex = i;
SelectedString = currentSelection;
}
}
}
Expand Down Expand Up @@ -257,4 +293,4 @@ protected enum SelectionState
protected abstract SelectionState PopulateItemsCore(string currentSelection);

}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,16 @@ public void CustomizeView(DSDropDownBase model, NodeView nodeView)
};

combo.DataContext = model;
//bind this combo box to the selected item hash

var bindingVal = new System.Windows.Data.Binding("Items") { Mode = BindingMode.TwoWay, Source = model };
// bind this combo box to the selected item hash
var bindingVal = new System.Windows.Data.Binding("Items")
{
Mode = BindingMode.TwoWay,
Source = model
};
combo.SetBinding(ItemsControl.ItemsSourceProperty, bindingVal);

//bind the selected index to the
// bind the selected index to the model property SelectedIndex
var indexBinding = new Binding("SelectedIndex")
{
Mode = BindingMode.TwoWay,
Expand Down
1 change: 1 addition & 0 deletions test/DynamoCoreTests/DynamoCoreTests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
<Compile Include="MockMaker.cs" />
<Compile Include="NodeConstructionTests.cs" />
<Compile Include="Nodes\DictionaryTests.cs" />
<Compile Include="Nodes\DropDownTests.cs" />
<Compile Include="NodeToCodeTest.cs" />
<Compile Include="PresetsTests.cs" />
<Compile Include="PeriodicEvaluationTests.cs" />
Expand Down
167 changes: 167 additions & 0 deletions test/DynamoCoreTests/Nodes/DropDownTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using CoreNodeModels;
using Dynamo.PackageManager;
using NUnit.Framework;
using SystemTestServices;

namespace Dynamo.Tests.Nodes
{
[TestFixture]
public class DropDownTests : DynamoModelTestBase
{
protected override void GetLibrariesToPreload(List<string> libraries)
{
libraries.Add("DesignScriptBuiltin.dll");
libraries.Add("DSCoreNodes.dll");
base.GetLibrariesToPreload(libraries);
}


[Test]
public void OpenJsonDYNwithSelectionNode()
{
// Define package loading reference path
var dir = SystemTestBase.GetTestDirectory(ExecutingDirectory);
var pkgDir = Path.Combine(dir, "pkgs\\Dynamo Samples");
var pkgMan = this.CurrentDynamoModel.GetPackageManagerExtension();
var loader = pkgMan.PackageLoader;
var pkg = loader.ScanPackageDirectory(pkgDir);

// Load the sample package
loader.Load(pkg);
// Assert expected package was loaded
Assert.AreEqual(pkg.Name, "Dynamo Samples");

// Run the graph with correct info serialized, node should deserialize to correct selection
string path = Path.Combine(TestDirectory, "pkgs", "Dynamo Samples", "extra", "DropDownSample.dyn");
RunModel(path);

var node = CurrentDynamoModel.CurrentWorkspace.Nodes.FirstOrDefault();
// Second selection selected
Assert.AreEqual(1, node.GetType().GetProperty("SelectedIndex").GetValue(node));
Assert.AreEqual("1", node.GetType().GetProperty("SelectedString").GetValue(node));
}


[Test]
public void OpenJsonDYNwithSelectionNodeAndWrongSelectionIndexSerialized()
{
// Define package loading reference path
var dir = SystemTestBase.GetTestDirectory(ExecutingDirectory);
var pkgDir = Path.Combine(dir, "pkgs\\Dynamo Samples");
var pkgMan = this.CurrentDynamoModel.GetPackageManagerExtension();
var loader = pkgMan.PackageLoader;
var pkg = loader.ScanPackageDirectory(pkgDir);

// Load the sample package
loader.Load(pkg);
// Assert expected package was loaded
Assert.AreEqual(pkg.Name, "Dynamo Samples");

// Run the graph with incorrect SelectedIndex serialized,
// this could be across host versions, index changed in newer version of host
// node should still deserialize to correct selection
string path = Path.Combine(TestDirectory, "pkgs", "Dynamo Samples", "extra", "DropDownSampleWithWrongIndex.dyn");
RunModel(path);

var node = CurrentDynamoModel.CurrentWorkspace.Nodes.FirstOrDefault();
// Second selection selected
Assert.AreEqual(1, node.GetType().GetProperty("SelectedIndex").GetValue(node));
Assert.AreEqual("1", node.GetType().GetProperty("SelectedString").GetValue(node));
}

[Test]
public void OpenXmlDYNwithSelectionNode()
{

// Define package loading reference path
var dir = SystemTestBase.GetTestDirectory(ExecutingDirectory);
var pkgDir = Path.Combine(dir, "pkgs\\Dynamo Samples");
var pkgMan = this.CurrentDynamoModel.GetPackageManagerExtension();
var loader = pkgMan.PackageLoader;
var pkg = loader.ScanPackageDirectory(pkgDir);

// Load the sample package
loader.Load(pkg);
// Assert expected package was loaded
Assert.AreEqual(pkg.Name, "Dynamo Samples");

// Run the graph with correct info serialized, node should deserialize to correct selection
string path = Path.Combine(TestDirectory, "pkgs", "Dynamo Samples", "extra", "DropDownSample_1Dot3.dyn");
RunModel(path);

var node = CurrentDynamoModel.CurrentWorkspace.Nodes.FirstOrDefault();
// Second selection selected
Assert.AreEqual(1, node.GetType().GetProperty("SelectedIndex").GetValue(node));
Assert.AreEqual("1", node.GetType().GetProperty("SelectedString").GetValue(node));
}

[Test]
public void Save_NothingSelected()
{
Assert.AreEqual(
"-1",
DSDropDownBase.SaveSelectedIndexImpl(-1, TestList()));
}

[Test]
public void Save_NothingInList()
{
Assert.AreEqual("-1", DSDropDownBase.SaveSelectedIndexImpl(5, new List<DynamoDropDownItem>()));
}

[Test]
public void Save_SelectedIndex()
{
Assert.AreEqual(
"2:banana:blueberry",
DSDropDownBase.SaveSelectedIndexImpl(2, TestList()));
}

[Test]
public void Load_NothingSelected()
{
Assert.AreEqual(-1, DSDropDownBase.ParseSelectedIndexImpl("-1", TestList()));
}

[Test]
public void Load_Selection()
{
Assert.AreEqual(2, DSDropDownBase.ParseSelectedIndexImpl("2:banana:blueberry", TestList()));
}

[Test]
public void Load_SelectionIndexOnly()
{
Assert.AreEqual(2, DSDropDownBase.ParseSelectedIndexImpl("2", TestList()));
}

[Test]
public void Load_SelectionIndexOutOfRange()
{
Assert.AreEqual(-1, DSDropDownBase.ParseSelectedIndexImpl("12", TestList()));
}

[Test]
public void Load_SelectionIndexNoNameMatch()
{
Assert.AreEqual(-1, DSDropDownBase.ParseSelectedIndexImpl("2:foo", TestList()));
}

private static List<DynamoDropDownItem> TestList()
{
var items = new List<DynamoDropDownItem>
{
new DynamoDropDownItem("cat", "cat"),
new DynamoDropDownItem("dog", "dog"),
new DynamoDropDownItem("banana:blueberry", "stuff"),
new DynamoDropDownItem("!@#$%%%^&*()", "craziness")
};

return items;
}

}
}
81 changes: 0 additions & 81 deletions test/DynamoCoreWpfTests/DropDownTests.cs

This file was deleted.

Loading