Skip to content
This repository was archived by the owner on Oct 16, 2020. It is now read-only.

Commit debb148

Browse files
committed
If properties on a markup extension (for example a binding) is modified after the markup extension was set on a property, and these property changes effect how the markup extension can be printed in XAML, the markup extension was not updated properly.
1 parent 8de9207 commit debb148

2 files changed

Lines changed: 53 additions & 12 deletions

File tree

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -319,8 +319,7 @@ public void AddBindingWithStaticResource()
319319
AssertLog("");
320320
}
321321

322-
[Test]
323-
public void AddBindingWithStaticResourceWhereResourceOnSameElement()
322+
void AddBindingWithStaticResourceWhereResourceOnSameElement(bool setBindingPropertiesAfterSet)
324323
{
325324
DesignItem button = CreateCanvasContext("<Button/>");
326325
DesignItem canvas = button.Parent;
@@ -334,10 +333,17 @@ public void AddBindingWithStaticResourceWhereResourceOnSameElement()
334333
resProp.CollectionElements.Add(exampleClassItem);
335334

336335
DesignItem bindingItem = canvas.Services.Component.RegisterComponentForDesigner(new Binding());
337-
bindingItem.Properties["Path"].SetValue("StringProp");
338-
bindingItem.Properties["Source"].SetValue(new StaticResourceExtension());
339-
bindingItem.Properties["Source"].Value.Properties["ResourceKey"].SetValue("bindingSource");
336+
if (!setBindingPropertiesAfterSet) {
337+
bindingItem.Properties["Path"].SetValue("StringProp");
338+
bindingItem.Properties["Source"].SetValue(new StaticResourceExtension());
339+
bindingItem.Properties["Source"].Value.Properties["ResourceKey"].SetValue("bindingSource");
340+
}
340341
textBox.Properties[TextBox.TextProperty].SetValue(bindingItem);
342+
if (setBindingPropertiesAfterSet) {
343+
bindingItem.Properties["Path"].SetValue("StringProp");
344+
bindingItem.Properties["Source"].SetValue(new StaticResourceExtension());
345+
bindingItem.Properties["Source"].Value.Properties["ResourceKey"].SetValue("bindingSource");
346+
}
341347

342348
string expectedXaml = "<Button />\n" +
343349
"<TextBox>\n" +
@@ -350,6 +356,18 @@ public void AddBindingWithStaticResourceWhereResourceOnSameElement()
350356
AssertCanvasDesignerOutput(expectedXaml, button.Context);
351357
AssertLog("");
352358
}
359+
360+
[Test]
361+
public void AddBindingWithStaticResourceWhereResourceOnSameElement()
362+
{
363+
AddBindingWithStaticResourceWhereResourceOnSameElement(false);
364+
}
365+
366+
[Test]
367+
public void AddBindingWithStaticResourceWhereResourceOnSameElementAlt()
368+
{
369+
AddBindingWithStaticResourceWhereResourceOnSameElement(true);
370+
}
353371
}
354372

355373
public class MyMultiConverter : IMultiValueConverter

src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Collections.Generic;
66
using System.ComponentModel;
77
using System.Diagnostics;
8+
using System.Linq;
89
using System.Windows.Markup;
910
using System.Xml;
1011
using System.Windows.Data;
@@ -151,8 +152,9 @@ internal static string GetContentPropertyName(Type elementType)
151152
}
152153

153154
internal override void AddNodeTo(XamlProperty property)
154-
{
155-
if (!UpdateXmlAttribute(true)) {
155+
{
156+
XamlObject holder;
157+
if (!UpdateXmlAttribute(true, out holder)) {
156158
property.AddChildNodeToProperty(element);
157159
}
158160
UpdateMarkupExtensionChain();
@@ -164,7 +166,8 @@ internal override void RemoveNodeFromParent()
164166
XmlAttribute.OwnerElement.RemoveAttribute(XmlAttribute.Name);
165167
xmlAttribute = null;
166168
} else {
167-
if (!UpdateXmlAttribute(false)) {
169+
XamlObject holder;
170+
if (!UpdateXmlAttribute(false, out holder)) {
168171
element.ParentNode.RemoveChild(element);
169172
}
170173
}
@@ -175,8 +178,28 @@ internal override void RemoveNodeFromParent()
175178
//TODO: reseting path property for binding doesn't work in XamlProperty
176179
//use CanResetValue()
177180
internal void OnPropertyChanged(XamlProperty property)
178-
{
179-
UpdateXmlAttribute(false);
181+
{
182+
XamlObject holder;
183+
if (!UpdateXmlAttribute(false, out holder)) {
184+
if (holder != null &&
185+
holder.XmlAttribute != null) {
186+
holder.XmlAttribute.OwnerElement.RemoveAttributeNode(holder.XmlAttribute);
187+
holder.xmlAttribute = null;
188+
holder.ParentProperty.AddChildNodeToProperty(holder.element);
189+
190+
bool isThisUpdated = false;
191+
foreach(XamlObject propXamlObject in holder.Properties.Where((prop) => prop.IsSet).Select((prop) => prop.PropertyValue).OfType<XamlObject>()) {
192+
XamlObject innerHolder;
193+
bool updateResult = propXamlObject.UpdateXmlAttribute(true, out innerHolder);
194+
Debug.Assert(updateResult);
195+
196+
if (propXamlObject == this)
197+
isThisUpdated = true;
198+
}
199+
if (!isThisUpdated)
200+
this.UpdateXmlAttribute(true, out holder);
201+
}
202+
}
180203
UpdateMarkupExtensionChain();
181204

182205
if (property == NameProperty) {
@@ -194,9 +217,9 @@ void UpdateMarkupExtensionChain()
194217
}
195218
}
196219

197-
bool UpdateXmlAttribute(bool force)
220+
bool UpdateXmlAttribute(bool force, out XamlObject holder)
198221
{
199-
var holder = FindXmlAttributeHolder();
222+
holder = FindXmlAttributeHolder();
200223
if (holder == null && force && IsMarkupExtension) {
201224
holder = this;
202225
}

0 commit comments

Comments
 (0)