Browse Source

Fixed so markup extensions where property is set by a StaticResource checks if the referenced resource is declared locally, and it its declared locally it forces the markup extension to be printed as element and not as shorthand XAML markup extension code. This is so the StaticResource can find the correct resource.

Also fixed so Resources element is always left first among the child elements when inserting new child.
pull/53/merge
Tobias Gummesson 12 years ago committed by Siegfried Pammer
parent
commit
d4beb03306
  1. 114
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/Designer/ModelTests.cs
  2. 40
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs
  3. 25
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs
  4. 9
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs

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

@ -1,18 +1,18 @@ @@ -1,18 +1,18 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using NUnit.Framework;
using ICSharpCode.WpfDesign.Designer;
using ICSharpCode.WpfDesign.Designer.Xaml;
using ICSharpCode.WpfDesign.Designer.Services;
using System;
using System.Text;
using System.IO;
using System.Xml;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using NUnit.Framework;
using ICSharpCode.WpfDesign.Designer;
using ICSharpCode.WpfDesign.Designer.Xaml;
using ICSharpCode.WpfDesign.Designer.Services;
namespace ICSharpCode.WpfDesign.Tests.Designer
{
@ -270,6 +270,86 @@ namespace ICSharpCode.WpfDesign.Tests.Designer @@ -270,6 +270,86 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
AssertCanvasDesignerOutput(expectedXaml, button.Context);
AssertLog("");
}
[Test]
public void AddSimpleBinding()
{
DesignItem button = CreateCanvasContext("<Button/>");
DesignItem canvas = button.Parent;
DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
canvas.Properties["Children"].CollectionElements.Add(textBox);
textBox.Properties[TextBox.TextProperty].SetValue(new Binding());
textBox.Properties[TextBox.TextProperty].Value.Properties["Path"].SetValue("SomeProperty");
string expectedXaml = "<Button />\n" +
"<TextBox Text=\"{Binding Path=SomeProperty}\" />\n";
AssertCanvasDesignerOutput(expectedXaml, button.Context);
AssertLog("");
}
[Test]
public void AddBindingWithStaticResource()
{
DesignItem button = CreateCanvasContext("<Button/>");
DesignItem canvas = button.Parent;
DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
canvas.Properties["Children"].CollectionElements.Add(textBox);
DesignItemProperty resProp = canvas.Properties.GetProperty("Resources");
Assert.IsTrue(resProp.IsCollection);
DesignItem exampleClassItem = canvas.Services.Component.RegisterComponentForDesigner(new ExampleClass());
exampleClassItem.Key = "bindingSource";
resProp.CollectionElements.Add(exampleClassItem);
DesignItem bindingItem = canvas.Services.Component.RegisterComponentForDesigner(new Binding());
textBox.Properties[TextBox.TextProperty].SetValue(bindingItem);
bindingItem.Properties["Path"].SetValue("StringProp");
bindingItem.Properties["Source"].SetValue(new StaticResourceExtension());
bindingItem.Properties["Source"].Value.Properties["ResourceKey"].SetValue("bindingSource");
string expectedXaml = "<Canvas.Resources>\n" +
" <t:ExampleClass x:Key=\"bindingSource\" />\n" +
"</Canvas.Resources>\n" +
"<Button />\n" +
"<TextBox Text=\"{Binding Path=StringProp, Source={StaticResource ResourceKey=bindingSource}}\" />";
AssertCanvasDesignerOutput(expectedXaml, button.Context);
AssertLog("");
}
[Test]
public void AddBindingWithStaticResourceWhereResourceOnSameElement()
{
DesignItem button = CreateCanvasContext("<Button/>");
DesignItem canvas = button.Parent;
DesignItem textBox = canvas.Services.Component.RegisterComponentForDesigner(new TextBox());
canvas.Properties["Children"].CollectionElements.Add(textBox);
DesignItemProperty resProp = textBox.Properties.GetProperty("Resources");
Assert.IsTrue(resProp.IsCollection);
DesignItem exampleClassItem = canvas.Services.Component.RegisterComponentForDesigner(new ExampleClass());
exampleClassItem.Key = "bindingSource";
resProp.CollectionElements.Add(exampleClassItem);
DesignItem bindingItem = canvas.Services.Component.RegisterComponentForDesigner(new Binding());
bindingItem.Properties["Path"].SetValue("StringProp");
bindingItem.Properties["Source"].SetValue(new StaticResourceExtension());
bindingItem.Properties["Source"].Value.Properties["ResourceKey"].SetValue("bindingSource");
textBox.Properties[TextBox.TextProperty].SetValue(bindingItem);
string expectedXaml = "<Button />\n" +
"<TextBox>\n" +
" <TextBox.Resources>\n" +
" <t:ExampleClass x:Key=\"bindingSource\" />\n" +
" </TextBox.Resources>\n" +
" <Binding Path=\"StringProp\" Source=\"{StaticResource ResourceKey=bindingSource}\" />\n" +
"</TextBox>";
AssertCanvasDesignerOutput(expectedXaml, button.Context);
AssertLog("");
}
}
public class MyMultiConverter : IMultiValueConverter
@ -284,4 +364,14 @@ namespace ICSharpCode.WpfDesign.Tests.Designer @@ -284,4 +364,14 @@ namespace ICSharpCode.WpfDesign.Tests.Designer
return new object[targetTypes.Length];
}
}
public class ExampleClass
{
string stringProp;
public string StringProp {
get { return stringProp; }
set { stringProp = value; }
}
}
}

40
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/MarkupExtensionPrinter.cs

@ -22,6 +22,35 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -22,6 +22,35 @@ namespace ICSharpCode.WpfDesign.XamlDom
obj.ElementType == typeof(System.Windows.Data.PriorityBinding)) {
return false;
}
foreach (var property in obj.Properties.Where((prop) => prop.IsSet))
{
var value = property.PropertyValue;
if (value is XamlTextValue)
continue;
else
{
XamlObject xamlObject = value as XamlObject;
if (xamlObject == null || !xamlObject.IsMarkupExtension)
return false;
else {
var staticResource = xamlObject.Instance as System.Windows.StaticResourceExtension;
if (staticResource != null &&
staticResource.ResourceKey != null) {
XamlObject parent = GetNonMarkupExtensionParent(xamlObject);
if (parent != null) {
var parentLocalResource = parent.ServiceProvider.Resolver.FindLocalResource(staticResource.ResourceKey);
// If resource with the specified key is declared locally on the same object as the StaticResource is being used the markup extension
// must be printed as element to find the resource, otherwise it will search from parent-parent and find none or another resource.
if (parentLocalResource != null)
return false;
}
}
}
}
}
return true;
}
@ -58,5 +87,16 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -58,5 +87,16 @@ namespace ICSharpCode.WpfDesign.XamlDom
sb.Append("}");
return sb.ToString();
}
private static XamlObject GetNonMarkupExtensionParent(XamlObject markupExtensionObject)
{
System.Diagnostics.Debug.Assert(markupExtensionObject.IsMarkupExtension);
XamlObject obj = markupExtensionObject;
while (obj != null && obj.IsMarkupExtension) {
obj = obj.ParentObject;
}
return obj;
}
}
}

25
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs

@ -5,6 +5,7 @@ using System; @@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Xml;
using System.Windows;
@ -267,6 +268,13 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -267,6 +268,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
oldPropertyElement.ParentNode.RemoveChild(oldPropertyElement);
}
}
bool IsFirstChildResources(XamlObject obj)
{
return obj.XmlElement.FirstChild != null &&
obj.XmlElement.FirstChild.Name.EndsWith("." + XamlConstants.ResourcesPropertyName) &&
obj.Properties.Where((prop) => prop.IsResources).FirstOrDefault() != null;
}
XmlElement CreatePropertyElement()
{
@ -287,11 +295,22 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -287,11 +295,22 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
if (_propertyElement == null) {
if (PropertyName == parentObject.ContentPropertyName) {
parentObject.XmlElement.InsertBefore(newChildNode, parentObject.XmlElement.FirstChild);
if (IsFirstChildResources(parentObject)) {
// Resources element should always be first
parentObject.XmlElement.InsertAfter(newChildNode, parentObject.XmlElement.FirstChild);
}
else
parentObject.XmlElement.InsertBefore(newChildNode, parentObject.XmlElement.FirstChild);
return;
}
_propertyElement = CreatePropertyElement();
parentObject.XmlElement.InsertBefore(_propertyElement, parentObject.XmlElement.FirstChild);
_propertyElement = CreatePropertyElement();
if (IsFirstChildResources(parentObject)) {
// Resources element should always be first
parentObject.XmlElement.InsertAfter(_propertyElement, parentObject.XmlElement.FirstChild);
}
else
parentObject.XmlElement.InsertBefore(_propertyElement, parentObject.XmlElement.FirstChild);
}
_propertyElement.AppendChild(newChildNode);
}

9
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlTypeResolverProvider.cs

@ -96,5 +96,14 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -96,5 +96,14 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
return null;
}
public object FindLocalResource(object key)
{
FrameworkElement el = containingObject.Instance as FrameworkElement;
if (el != null) {
return el.Resources[key];
}
return null;
}
}
}

Loading…
Cancel
Save