Skip to content
This repository has been archived by the owner on Feb 20, 2022. It is now read-only.

61 behaviors are not attached to nested fields #62

Merged
merged 2 commits into from
Feb 22, 2015
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
4 changes: 2 additions & 2 deletions NZazu/FieldBehavior/NZazuFieldBehaviorFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ public INZazuWpfFieldBehavior CreateFieldBehavior(BehaviorDefinition behaviorDef
if (behaviorDefinition == null) throw new ArgumentNullException("behaviorDefinition");
if (string.IsNullOrWhiteSpace(behaviorDefinition.Name)) throw new ArgumentException("BehaviorDefinition.Name should be set");

var fieldTypes = BehaviorExtender.Instance.Behaviors.ToArray();
var behaviorTypes = BehaviorExtender.Instance.Behaviors.ToArray();
var behaviorType =
fieldTypes.FirstOrDefault(
behaviorTypes.FirstOrDefault(
kvp => string.Compare(kvp.Key, behaviorDefinition.Name, StringComparison.Ordinal) == 0).Value;

if (behaviorType == null) return null;
Expand Down
45 changes: 26 additions & 19 deletions NZazu/NZazuView.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,13 +160,12 @@ public INZazuWpfField GetField(string key)

public bool TryGetField(string key, out INZazuWpfField field)
{
return _fields.TryGetValue(key, out field)
|| _groupFields.TryGetValue(key, out field);
return _fields.TryGetValue(key, out field);
}

public Dictionary<string, string> GetFieldValues()
{
return (_fields.Concat(_groupFields))
return _fields
.Where(f => f.Value.IsEditable)
.ToDictionary(f => f.Key, f => f.Value.StringValue);
}
Expand All @@ -179,7 +178,6 @@ public ValueCheckResult Validate()
}

private readonly IDictionary<string, INZazuWpfField> _fields = new Dictionary<string, INZazuWpfField>();
private readonly IDictionary<string, INZazuWpfField> _groupFields = new Dictionary<string, INZazuWpfField>();

private void UpdateFields(
FormDefinition formDefinition,
Expand All @@ -197,7 +195,9 @@ private void UpdateFields(
AttachBehavior(formDefinition, fieldBehaviorFactory);

var layout = resolveLayout.Resolve(formDefinition.Layout);
layout.DoLayout(Layout, _fields.Values, resolveLayout);

var parentFields = FormDefinition.Fields.Select(fd => GetField(fd.Key));
layout.DoLayout(Layout, parentFields, resolveLayout);

this.SetFieldValues(FormData.Values);
}
Expand Down Expand Up @@ -231,7 +231,7 @@ private void AddGroupFieldKeys(INZazuWpfGroupField groupField)
if (groupField == null) return;
foreach (var field in groupField.Fields)
{
_groupFields.Add(field.Key, field);
_fields.Add(field.Key, field);
AddGroupFieldKeys(field as INZazuWpfGroupField);
}
}
Expand All @@ -240,34 +240,41 @@ private void DisposeFields()
{
DetachBehavior();
_fields.Clear();
_groupFields.Clear();
}

private void AttachBehavior(FormDefinition formDefinition, INZazuWpfFieldBehaviorFactory fieldBehaviorFactory)
{
foreach (var fieldDefinition in formDefinition.Fields)
{
if (fieldDefinition.Behavior == null || string.IsNullOrWhiteSpace(fieldDefinition.Behavior.Name)) continue; // lets ship "nothing"
formDefinition.Fields.ToList().ForEach(f => AttachBehavior(fieldBehaviorFactory, f));
}

private void AttachBehavior(INZazuWpfFieldBehaviorFactory fieldBehaviorFactory, FieldDefinition fieldDefinition)
{
if (fieldDefinition.Behavior != null && !string.IsNullOrWhiteSpace(fieldDefinition.Behavior.Name))
{
var behavior = fieldBehaviorFactory.CreateFieldBehavior(fieldDefinition.Behavior);
var field = GetField(fieldDefinition.Key) as NZazuField;
if (field == null) return;

INZazuWpfField field;
if (!TryGetField(fieldDefinition.Key, out field)) return;
behavior.AttachTo(field, this);
field.Behavior = behavior;
}

if (fieldDefinition.Fields == null) return;
fieldDefinition.Fields.ToList().ForEach(f => AttachBehavior(fieldBehaviorFactory, f));
}


private void DetachBehavior()
{
if (_fields == null) return;
DetachBehavior(_fields.Values);
}

foreach (var field in _fields)
private static void DetachBehavior(IEnumerable<INZazuWpfField> fields)
{
foreach (var field in fields)
{
// detach field
if (field.Value == null || field.Value.Behavior == null) return;
field.Value.Behavior.Detach();
field.Value.Behavior = null;
if (field == null || field.Behavior == null) continue;
field.Behavior.Detach();
field.Behavior = null;
}
}
}
Expand Down
36 changes: 18 additions & 18 deletions NZazu/NZazuView_Should.cs
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ public void Preserve_Formdata_if_FormDefinition_changed()
formData.Values.ShouldBeEquivalentTo(actual);

fieldDefinition.Prompt = "Login";
var changedFormDefinition = new FormDefinition {Fields = new[] {fieldDefinition}};
var changedFormDefinition = new FormDefinition { Fields = new[] { fieldDefinition } };

// it is ugly to attach to depProperty.changed. It goes like this
// https://social.msdn.microsoft.com/Forums/vstudio/en-US/262df30c-8383-4d5c-8d76-7b8e2cea51de/how-do-you-attach-a-change-event-to-a-dependency-property?forum=wpf
Expand All @@ -290,7 +290,7 @@ public void Preserve_Formdata_if_FormDefinition_changed()
EventHandler handler = (sender, args) => { formDefinitionChanged = true; };
dpDescriptor.AddValueChanged(sut, handler);
try { sut.FormDefinition = changedFormDefinition; }
finally { dpDescriptor.RemoveValueChanged(sut, handler); }
finally { dpDescriptor.RemoveValueChanged(sut, handler); }

formDefinitionChanged.Should().BeTrue();

Expand All @@ -316,36 +316,36 @@ public void Throw_KeyNotFoundException_On_GetField_For_Wrong_Key()
}

[Test]
public void Attach_And_Detach_Behavior_To_Field()
public void Attach_And_Detach_Behavior_To_Fields()
{
const string key = "key";
const string value = "value";

// lets mock the behavior
var behaviorDefinition = new BehaviorDefinition { Name = "Empty" };
var behavior = Substitute.For<INZazuWpfFieldBehavior>();
var fieldDefinition = new FieldDefinition

var fields = new[]
{
Key = key,
Type = "string",
Prompt = "Name",
Behavior = behaviorDefinition
new FieldDefinition { Key = "a", Type = "string", Behavior = behaviorDefinition },
new FieldDefinition { Key = "b", Type = "group",
Fields = new []
{
new FieldDefinition { Key= "b.a", Type = "string", Behavior = behaviorDefinition}
}}
};
var formDefinition = new FormDefinition { Fields = new[] { fieldDefinition } };
var formData = new FormData(new Dictionary<string, string> { { key, value } });
var formDefinition = new FormDefinition { Fields = fields };

var behaviorFactory = Substitute.For<INZazuWpfFieldBehaviorFactory>();
behaviorFactory.CreateFieldBehavior(Arg.Any<BehaviorDefinition>()).ReturnsForAnyArgs(behavior);

// amke sure an attach happens
var sut = new NZazuView { FieldBehaviorFactory = behaviorFactory, FormDefinition = formDefinition, FormData = formData };
// make sure an attach happens
var sut = new NZazuView { FieldBehaviorFactory = behaviorFactory, FormDefinition = formDefinition };
sut.Should().NotBeNull();

behavior.Received().AttachTo(Arg.Any<INZazuWpfField>(), sut);
behavior.Received(2).AttachTo(Arg.Any<INZazuWpfField>(), sut);
behavior.ClearReceivedCalls();

// now lets create a ner form and detach the existing behavior
sut.FormDefinition = new FormDefinition { Fields = new[] { fieldDefinition } };
behavior.ReceivedWithAnyArgs().Detach();
sut.FormDefinition = new FormDefinition { Fields = fields };
behavior.ReceivedWithAnyArgs(2).Detach();
}

[Test]
Expand Down
20 changes: 18 additions & 2 deletions NZazuFiddle/Samples/BehaviorSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ namespace NZazuFiddle.Samples
// ReSharper disable once ClassNeverInstantiated.Global
class BehaviorSample : SampleBase
{
public BehaviorSample() : base(40)
public BehaviorSample()
: base(40)
{
// register behavior
BehaviorExtender.Register<OpenUrlOnStringEnterBehavior>("OpenUrlOnStringEnter");
Expand Down Expand Up @@ -46,18 +47,33 @@ public BehaviorSample() : base(40)
new CheckDefinition { Type = "required" }
},
Behavior = new BehaviorDefinition { Name = "OpenUrlOnStringEnter" },
},
new FieldDefinition
{
Key ="group",
Type = "group",
Fields = new []
{
new FieldDefinition
{
Key = "nested.comment", Type ="string",
Behavior = new BehaviorDefinition { Name = "OpenUrlOnStringEnter" }
}
}
}
}
},
new Dictionary<string, string>
{
{ "comment", "type in a url like http://google.de and open it with STRG+Enter" },
{ "comment", "type in a url like http://google.de and open it with Ctrl+Enter" },
{ "nested.comment", "type in a url like http://google.de and open it with Ctrl+Enter" },
})
};
}

#region behavior and behavior test

// ReSharper disable once ClassNeverInstantiated.Local
private class OpenUrlOnStringEnterBehavior : INZazuWpfFieldBehavior
{
private Control _control;
Expand Down
2 changes: 1 addition & 1 deletion solution.targets
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<PackageVersion>0.2.6.$(Build)</PackageVersion>
<PackageVersion>0.2.7.$(Build)</PackageVersion>
</PropertyGroup>

</Project>