Browse Source

Set Canvas.Left+Canvas.Top attached properties when resizing a control inside a Canvas.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2413 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
a4035d10e4
  1. 4
      src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml
  2. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs
  3. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs
  4. 6
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs
  5. 64
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasChildResizeSupport.cs
  6. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultChildResizeSupport.cs
  7. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs
  8. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs
  9. 15
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs
  10. 51
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/UndoService.cs
  11. 3
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj
  12. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs
  13. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs
  14. 6
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs
  15. 16
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs
  16. 49
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Tests/ModelTests.cs
  17. 25
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlObject.cs
  18. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
  19. 30
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlProperty.cs
  20. 39
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/ExampleService.cs
  21. 13
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/SimpleLoadTests.cs
  22. 1
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/WpfDesign.XamlDom.Tests.csproj
  23. 41
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs
  24. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/BehaviorExtension.cs
  25. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs
  26. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Func.cs
  27. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataSource.cs
  28. 4
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultiSelectionDataSource.cs
  29. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/PropertyEditorBindingHelper.cs
  30. 2
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

4
src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml

@ -25,7 +25,9 @@ @@ -25,7 +25,9 @@
Title="WindowTitle"
BorderThickness="10" Width="400" Height="300">
<StackPanel>
<Canvas Height="50"></Canvas>
<Canvas Height="50">
<Button Width="60" Height="25.96">CB</Button>
</Canvas>
<Button>Button 1</Button>
<Button>Button 2</Button>
<TabControl Width="300" MinHeight="100">

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs

@ -64,7 +64,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls @@ -64,7 +64,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
public void CopyTo(AdornerPanel[] array, int arrayIndex)
{
Linq.ToArray(this).CopyTo(array, arrayIndex);
Func.ToArray(this).CopyTo(array, arrayIndex);
}
public bool Remove(AdornerPanel item)

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs

@ -99,7 +99,7 @@ namespace ICSharpCode.WpfDesign.Designer @@ -99,7 +99,7 @@ namespace ICSharpCode.WpfDesign.Designer
if (useCategories) {
List<PropertyEditorCategoryView> categories = new List<PropertyEditorCategoryView>();
foreach (IPropertyEditorDataProperty p in Linq.Sort(dataSource.Properties, ComparePropertyNames)) {
foreach (IPropertyEditorDataProperty p in Func.Sort(dataSource.Properties, ComparePropertyNames)) {
if (p.Name == "Name") {
continue;
}
@ -117,7 +117,7 @@ namespace ICSharpCode.WpfDesign.Designer @@ -117,7 +117,7 @@ namespace ICSharpCode.WpfDesign.Designer
}
} else {
PropertyGridView grid = new PropertyGridView();
foreach (IPropertyEditorDataProperty p in Linq.Sort(dataSource.Properties, ComparePropertyNames)) {
foreach (IPropertyEditorDataProperty p in Func.Sort(dataSource.Properties, ComparePropertyNames)) {
if (p.Name == "Name") {
continue;
}

6
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs

@ -61,7 +61,10 @@ namespace ICSharpCode.WpfDesign.Designer @@ -61,7 +61,10 @@ namespace ICSharpCode.WpfDesign.Designer
void OnUndoExecuted(object sender, ExecutedRoutedEventArgs e)
{
IUndoAction action = Func.First(_undoService.UndoActions);
Debug.WriteLine("Undo " + action.Title);
_undoService.Undo();
_designContext.Services.Selection.SetSelectedComponents(action.AffectedElements);
}
void OnUndoCanExecute(object sender, CanExecuteRoutedEventArgs e)
@ -71,7 +74,10 @@ namespace ICSharpCode.WpfDesign.Designer @@ -71,7 +74,10 @@ namespace ICSharpCode.WpfDesign.Designer
void OnRedoExecuted(object sender, ExecutedRoutedEventArgs e)
{
IUndoAction action = Func.First(_undoService.RedoActions);
Debug.WriteLine("Redo " + action.Title);
_undoService.Redo();
_designContext.Services.Selection.SetSelectedComponents(action.AffectedElements);
}
void OnRedoCanExecute(object sender, CanExecuteRoutedEventArgs e)

64
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/CanvasChildResizeSupport.cs

@ -0,0 +1,64 @@ @@ -0,0 +1,64 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using ICSharpCode.WpfDesign.Extensions;
using System.Windows;
using System.Windows.Controls;
using ICSharpCode.WpfDesign.Adorners;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
/// <summary>
/// Provides <see cref="IChildResizeSupport"/> behavior for <see cref="Canvas"/>.
/// </summary>
[ExtensionFor(typeof(Canvas))]
public sealed class CanvasChildResizeSupport : BehaviorExtension, IChildResizeSupport
{
/// <inherits/>
protected override void OnInitialized()
{
base.OnInitialized();
this.ExtendedItem.AddBehavior(typeof(IChildResizeSupport), this);
}
/// <inherits/>
public bool CanResizeChild(DesignItem child)
{
return DefaultChildResizeSupport.Instance.CanResizeChild(child);
}
/// <inherits/>
public Placement GetPlacement(DesignItem child, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical)
{
return RootElementResizeSupport.Instance.GetPlacement(child, horizontalChange, verticalChange, horizontal, vertical);
}
/// <inherits/>
public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical)
{
RelativePlacement p = (RelativePlacement)GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical);
DefaultChildResizeSupport.Resize(childItem, p);
bool marginIsSet = childItem.Properties[FrameworkElement.MarginProperty].IsSet;
DesignItemProperty left = childItem.Properties.GetAttachedProperty(Canvas.LeftProperty);
DesignItemProperty top = childItem.Properties.GetAttachedProperty(Canvas.TopProperty);
if (left.IsSet) {
left.SetValue( p.XOffset + (double)left.ValueOnInstance);
} else if (p.XOffset != 0 && !marginIsSet) {
left.SetValue( p.XOffset );
}
if (top.IsSet) {
top.SetValue( p.YOffset + (double)top.ValueOnInstance);
} else if (p.YOffset != 0 && !marginIsSet) {
top.SetValue( p.YOffset );
}
}
}
}

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/DefaultChildResizeSupport.cs

@ -66,10 +66,10 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -66,10 +66,10 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public void Resize(DesignItem childItem, double horizontalChange, double verticalChange, HorizontalAlignment horizontal, VerticalAlignment vertical)
{
RelativePlacement p = (RelativePlacement)GetPlacement(childItem, horizontalChange, verticalChange, horizontal, vertical);
Resize(childItem, p, horizontal, vertical);
Resize(childItem, p);
}
static void Resize(DesignItem childItem, RelativePlacement p, HorizontalAlignment horizontal, VerticalAlignment vertical)
internal static void Resize(DesignItem childItem, RelativePlacement p)
{
DesignItemProperty margin = childItem.Properties[FrameworkElement.MarginProperty];
if (margin.IsSet) {

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/PanelInstanceFactory.cs

@ -20,7 +20,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -20,7 +20,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
/// setting the Brush to null actually restores the transparent brush.
/// </summary>
[ExtensionFor(typeof(Panel))]
public class PanelInstanceFactory : CustomInstanceFactory
public sealed class PanelInstanceFactory : CustomInstanceFactory
{
Brush _transparentBrush = new SolidColorBrush(Colors.Transparent);
@ -92,7 +92,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -92,7 +92,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
PropertyDescriptor property = properties[_parent._propertyName];
if (property != null) {
if ((properties as System.Collections.IDictionary).IsReadOnly) {
properties = new PropertyDescriptorCollection(Linq.ToArray(properties));
properties = new PropertyDescriptorCollection(Func.ToArray(properties));
}
properties.Remove(property);
properties.Add(new ShadowPropertyDescriptor(_parent, property));

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs

@ -19,7 +19,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions @@ -19,7 +19,7 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
/// Draws a dotted line around selected UIElements.
/// </summary>
[ExtensionFor(typeof(UIElement))]
public class SelectedElementRectangleExtension : SelectionAdornerProvider
public sealed class SelectedElementRectangleExtension : SelectionAdornerProvider
{
/// <summary>
/// Creates a new SelectedElementRectangleExtension instance.

15
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs → src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Func.cs

@ -12,7 +12,7 @@ using System.Collections.Generic; @@ -12,7 +12,7 @@ using System.Collections.Generic;
namespace ICSharpCode.WpfDesign.Designer
{
// Static helpers that should become extension methods in the future
static class Linq
static class Func
{
public static T[] ToArray<T>(ICollection<T> collection)
{
@ -37,5 +37,18 @@ namespace ICSharpCode.WpfDesign.Designer @@ -37,5 +37,18 @@ namespace ICSharpCode.WpfDesign.Designer
Array.Sort(arr, comparison);
return arr;
}
/// <summary>
/// Returns the first element from <paramref name="input"/>.
/// </summary>
public static T First<T>(IEnumerable<T> input)
{
if (input == null)
throw new ArgumentNullException("input");
foreach (T item in input) {
return item;
}
throw new ArgumentException("input must not be an empty collection", "input");
}
}
}

51
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/UndoService.cs

@ -12,11 +12,27 @@ using System.Diagnostics; @@ -12,11 +12,27 @@ using System.Diagnostics;
namespace ICSharpCode.WpfDesign.Designer.Services
{
#region ITransactionItem
interface ITransactionItem
interface ITransactionItem : IUndoAction
{
void Do();
void Undo();
}
#endregion
#region IUndoAction
/// <summary>
/// Describes an action available on the undo or redo stack.
/// </summary>
public interface IUndoAction
{
/// <summary>
/// The list of elements affected by the action.
/// </summary>
ICollection<DesignItem> AffectedElements { get; }
/// <summary>
/// The title of the action.
/// </summary>
string Title { get; }
}
#endregion
@ -27,6 +43,17 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -27,6 +43,17 @@ namespace ICSharpCode.WpfDesign.Designer.Services
/// </summary>
sealed class UndoTransaction : ChangeGroup, ITransactionItem
{
readonly ICollection<DesignItem> affectedElements;
internal UndoTransaction(ICollection<DesignItem> affectedElements)
{
this.affectedElements = affectedElements;
}
public ICollection<DesignItem> AffectedElements {
get { return affectedElements; }
}
public enum TransactionState
{
Open,
@ -145,9 +172,9 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -145,9 +172,9 @@ namespace ICSharpCode.WpfDesign.Designer.Services
Stack<ITransactionItem> _undoStack = new Stack<ITransactionItem>();
Stack<ITransactionItem> _redoStack = new Stack<ITransactionItem>();
internal UndoTransaction StartTransaction()
internal UndoTransaction StartTransaction(ICollection<DesignItem> affectedItems)
{
UndoTransaction t = new UndoTransaction();
UndoTransaction t = new UndoTransaction(affectedItems);
_transactionStack.Push(t);
t.Committed += TransactionFinished;
t.RolledBack += TransactionFinished;
@ -219,25 +246,27 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -219,25 +246,27 @@ namespace ICSharpCode.WpfDesign.Designer.Services
/// <summary>
/// Gets the list of names of the available actions on the undo stack.
/// </summary>
public IEnumerable<string> UndoActions {
public IEnumerable<IUndoAction> UndoActions {
get {
foreach (ITransactionItem item in _undoStack) {
yield return item.Title;
}
return GetActions(_undoStack);
}
}
/// <summary>
/// Gets the list of names of the available actions on the undo stack.
/// </summary>
public IEnumerable<string> RedoActions {
public IEnumerable<IUndoAction> RedoActions {
get {
foreach (ITransactionItem item in _redoStack) {
yield return item.Title;
}
return GetActions(_redoStack);
}
}
static IEnumerable<IUndoAction> GetActions(Stack<ITransactionItem> stack)
{
foreach (ITransactionItem item in stack)
yield return item;
}
/// <summary>
/// Gets if there are redo actions available.
/// </summary>

3
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj

@ -70,13 +70,14 @@ @@ -70,13 +70,14 @@
<Compile Include="Controls\TypeEditors\BrushEditor.cs" />
<Compile Include="Controls\WindowClone.cs" />
<Compile Include="DesignPanel.cs" />
<Compile Include="Extensions\CanvasChildResizeSupport.cs" />
<Compile Include="Extensions\DefaultChildResizeSupport.cs" />
<Compile Include="Extensions\PanelInstanceFactory.cs" />
<Compile Include="Extensions\SelectedElementRectangleExtension.cs" />
<Compile Include="Extensions\TabItemClickableExtension.cs" />
<Compile Include="Extensions\TopLeftContainerDragHandle.cs" />
<Compile Include="Extensions\ResizeThumbExtension.cs" />
<Compile Include="Linq.cs" />
<Compile Include="Func.cs" />
<Compile Include="ServiceRequiredException.cs" />
<Compile Include="Services\ErrorService.cs" />
<Compile Include="Services\SelectionService.cs" />

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlComponentService.cs

@ -108,7 +108,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -108,7 +108,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
/// </summary>
internal void UnregisterAllComponents()
{
Array.ForEach(Linq.ToArray(_sites.Values), UnregisterComponentFromDesigner);
Array.ForEach(Func.ToArray(_sites.Values), UnregisterComponentFromDesigner);
_sites.Clear();
}
}

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs

@ -96,7 +96,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -96,7 +96,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
UndoService undoService = this.Services.GetService<UndoService>();
if (undoService == null)
throw new ServiceRequiredException(typeof(UndoService));
UndoTransaction g = undoService.StartTransaction();
UndoTransaction g = undoService.StartTransaction(new DesignItem[] { this });
g.Title = changeGroupTitle;
return g;
}

6
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs

@ -248,6 +248,12 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -248,6 +248,12 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
else
property.ResetInternal();
}
public System.Collections.Generic.ICollection<DesignItem> AffectedElements {
get {
return new DesignItem[] { property._designItem };
}
}
}
}
}

16
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs

@ -20,17 +20,15 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml @@ -20,17 +20,15 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
this._item = item;
}
public override DesignItemProperty this[DependencyProperty dependencyProperty] {
get {
//return new XamlModelProperty(_item, dependencyProperty);
return this[dependencyProperty.Name];
}
public override DesignItemProperty GetProperty(string name)
{
return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateProperty(name));
}
public override DesignItemProperty this[string name] {
get {
return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateProperty(name));
}
public override DesignItemProperty GetAttachedProperty(Type ownerType, string name)
{
return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateAttachedProperty(ownerType, name));
}
public override System.Collections.Generic.IEnumerator<DesignItemProperty> GetEnumerator()

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

@ -12,6 +12,7 @@ using System.Xml; @@ -12,6 +12,7 @@ using System.Xml;
using System.Diagnostics;
using NUnit.Framework;
using ICSharpCode.WpfDesign.Designer.Xaml;
using ICSharpCode.WpfDesign.Designer.Services;
namespace ICSharpCode.WpfDesign.Designer.Tests
{
@ -26,5 +27,53 @@ namespace ICSharpCode.WpfDesign.Designer.Tests @@ -26,5 +27,53 @@ namespace ICSharpCode.WpfDesign.Designer.Tests
AssertCanvasDesignerOutput(@"<Button Width=""100"" />", button.Context);
AssertLog("");
}
[Test]
public void UndoRedoTest()
{
DesignItem button = CreateCanvasContext("<Button/>");
UndoService s = button.Context.Services.GetService<UndoService>();
Assert.IsFalse(s.CanUndo);
Assert.IsFalse(s.CanRedo);
button.Properties["Width"].SetValue(100.0);
Assert.IsTrue(s.CanUndo);
Assert.IsFalse(s.CanRedo);
AssertCanvasDesignerOutput(@"<Button Width=""100"" />", button.Context);
s.Undo();
Assert.IsFalse(s.CanUndo);
Assert.IsTrue(s.CanRedo);
AssertCanvasDesignerOutput(@"<Button />", button.Context);
s.Redo();
Assert.IsTrue(s.CanUndo);
Assert.IsFalse(s.CanRedo);
AssertCanvasDesignerOutput(@"<Button Width=""100"" />", button.Context);
AssertLog("");
}
[Test]
public void UndoRedoChangeGroupTest()
{
DesignItem button = CreateCanvasContext("<Button/>");
UndoService s = button.Context.Services.GetService<UndoService>();
Assert.IsFalse(s.CanUndo);
Assert.IsFalse(s.CanRedo);
using (ChangeGroup g = button.OpenGroup("Resize")) {
button.Properties["Width"].SetValue(100.0);
button.Properties["Height"].SetValue(200.0);
g.Commit();
}
Assert.IsTrue(s.CanUndo);
Assert.IsFalse(s.CanRedo);
AssertCanvasDesignerOutput(@"<Button Width=""100"" Height=""200"" />", button.Context);
s.Undo();
Assert.IsFalse(s.CanUndo);
Assert.IsTrue(s.CanRedo);
AssertCanvasDesignerOutput(@"<Button />", button.Context);
s.Redo();
Assert.IsTrue(s.CanUndo);
Assert.IsFalse(s.CanRedo);
AssertCanvasDesignerOutput(@"<Button Width=""100"" Height=""200"" />", button.Context);
AssertLog("");
}
}
}

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

@ -99,7 +99,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -99,7 +99,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
throw new ArgumentNullException("propertyName");
foreach (XamlProperty p in properties) {
if (p.PropertyName == propertyName)
if (!p.IsAttached && p.PropertyName == propertyName)
return p;
}
PropertyDescriptorCollection propertyDescriptors = TypeDescriptor.GetProperties(instance);
@ -111,5 +111,28 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -111,5 +111,28 @@ namespace ICSharpCode.WpfDesign.XamlDom
properties.Add(newProperty);
return newProperty;
}
/// <summary>
/// Finds the specified property, or creates it if it doesn't exist.
/// </summary>
public XamlProperty FindOrCreateAttachedProperty(Type ownerType, string propertyName)
{
if (ownerType == null)
throw new ArgumentNullException("ownerType");
if (propertyName == null)
throw new ArgumentNullException("propertyName");
foreach (XamlProperty p in properties) {
if (p.IsAttached && p.PropertyTargetType == ownerType && p.PropertyName == propertyName)
return p;
}
XamlPropertyInfo info = XamlParser.TryFindAttachedProperty(ownerType, propertyName);
if (info == null) {
throw new ArgumentException("The attached property '" + propertyName + "' doesn't exist on " + ownerType.FullName, "propertyName");
}
XamlProperty newProperty = new XamlProperty(this, info);
properties.Add(newProperty);
return newProperty;
}
}
}

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs

@ -281,7 +281,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -281,7 +281,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
return new XamlNormalPropertyInfo(propertyInfo);
}
static XamlPropertyInfo TryFindAttachedProperty(Type elementType, string propertyName)
internal static XamlPropertyInfo TryFindAttachedProperty(Type elementType, string propertyName)
{
MethodInfo getMethod = elementType.GetMethod("Get" + propertyName, BindingFlags.Public | BindingFlags.Static);
MethodInfo setMethod = elementType.GetMethod("Set" + propertyName, BindingFlags.Public | BindingFlags.Static);

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

@ -24,7 +24,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -24,7 +24,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
XamlPropertyValue propertyValue;
List<XamlPropertyValue> collectionElements;
bool _isCollection;
bool isCollection;
static readonly IList<XamlPropertyValue> emptyCollectionElementsArray = new XamlPropertyValue[0];
@ -39,7 +39,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -39,7 +39,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
propertyValue.ParentProperty = this;
} else {
if (propertyInfo.IsCollection) {
_isCollection = true;
isCollection = true;
collectionElements = new List<XamlPropertyValue>();
}
}
@ -49,7 +49,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -49,7 +49,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
{
this.parentObject = parentObject;
this.propertyInfo = propertyInfo;
_isCollection = propertyInfo.IsCollection;
isCollection = propertyInfo.IsCollection;
}
/// <summary>
@ -73,6 +73,13 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -73,6 +73,13 @@ namespace ICSharpCode.WpfDesign.XamlDom
get { return propertyInfo.TargetType; }
}
/// <summary>
/// Gets if this property is an attached property.
/// </summary>
public bool IsAttached {
get { return propertyInfo.IsAttached; }
}
/// <summary>
/// Gets the return type of the property.
/// </summary>
@ -145,7 +152,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -145,7 +152,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
/// Gets if the property is a collection property.
/// </summary>
public bool IsCollection {
get { return _isCollection; }
get { return isCollection; }
}
/// <summary>
@ -370,8 +377,19 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -370,8 +377,19 @@ namespace ICSharpCode.WpfDesign.XamlDom
if (attribute != null) {
property.ParentObject.XmlElement.Attributes.Append(attribute);
} else if (textValue != null) {
property.ParentObject.XmlElement.SetAttribute(property.PropertyName, textValue);
attribute = property.ParentObject.XmlElement.GetAttributeNode(property.PropertyName);
string ns = property.ParentObject.OwnerDocument.GetNamespaceFor(property.PropertyTargetType);
string name;
if (property.IsAttached)
name = property.PropertyTargetType.Name + "." + property.PropertyName;
else
name = property.PropertyName;
if (property.ParentObject.XmlElement.GetPrefixOfNamespace(ns) == "") {
property.ParentObject.XmlElement.SetAttribute(name, textValue);
attribute = property.ParentObject.XmlElement.GetAttributeNode(name);
} else {
property.ParentObject.XmlElement.SetAttribute(name, ns, textValue);
attribute = property.ParentObject.XmlElement.GetAttributeNode(name, ns);
}
textValue = null;
} else {
property.AddChildNodeToProperty(textNode);

39
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/ExampleService.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Windows;
namespace ICSharpCode.WpfDesign.XamlDom.Tests
{
/// <summary>
/// Provides an example attached property.
/// </summary>
public static class ExampleService
{
public static readonly DependencyProperty ExampleProperty = DependencyProperty.RegisterAttached(
"Example", typeof(string), typeof(ExampleService)
);
public static string GetExample(DependencyObject element)
{
TestHelperLog.Log("ExampleService.GetExample");
return (string)element.GetValue(ExampleProperty);
}
public static void SetExample(DependencyObject element, string value)
{
TestHelperLog.Log("ExampleService.SetExample");
element.SetValue(ExampleProperty, value);
}
}
public class ExampleDependencyObject : DependencyObject
{
}
}

13
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/SimpleLoadTests.cs

@ -180,5 +180,18 @@ namespace ICSharpCode.WpfDesign.XamlDom.Tests @@ -180,5 +180,18 @@ namespace ICSharpCode.WpfDesign.XamlDom.Tests
</ExampleClassContainer>
");
}
[Test]
public void ExampleServiceTest()
{
TestLoading(@"
<t:ExampleDependencyObject
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:t=""clr-namespace:ICSharpCode.WpfDesign.XamlDom.Tests;assembly=ICSharpCode.WpfDesign.XamlDom.Tests""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
t:ExampleService.Example=""attached value"">
</t:ExampleDependencyObject>
");
}
}
}

1
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Tests/WpfDesign.XamlDom.Tests.csproj

@ -58,6 +58,7 @@ @@ -58,6 +58,7 @@
<Compile Include="AssemblyInfo.cs" />
<Compile Include="ExampleClass.cs" />
<Compile Include="ExampleClassContainer.cs" />
<Compile Include="ExampleService.cs" />
<Compile Include="SamplesTests.cs" />
<Compile Include="SimpleLoadTests.cs" />
<Compile Include="SystemTypesLoadTest.cs" />

41
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs

@ -103,14 +103,49 @@ namespace ICSharpCode.WpfDesign @@ -103,14 +103,49 @@ namespace ICSharpCode.WpfDesign
public abstract class DesignItemPropertyCollection : IEnumerable<DesignItemProperty>
{
/// <summary>
/// Gets the design item property representing the specified dependency property.
/// Gets the property with the specified name.
/// </summary>
public abstract DesignItemProperty this[DependencyProperty dependencyProperty] { get; }
public DesignItemProperty this[string name] {
get { return GetProperty(name); }
}
/// <summary>
/// Gets the property with the specified name.
/// </summary>
public abstract DesignItemProperty this[string name] { get; }
public DesignItemProperty this[DependencyProperty dependencyProperty] {
get { return GetProperty(dependencyProperty); }
}
/// <summary>
/// Gets the design item property with the specified name.
/// </summary>
public abstract DesignItemProperty GetProperty(string name);
/// <summary>
/// Gets the attached property on the specified owner with the specified name.
/// </summary>
public abstract DesignItemProperty GetAttachedProperty(Type ownerType, string name);
/// <summary>
/// Gets the design item property representing the specified dependency property.
/// The property must not be an attached property.
/// </summary>
public DesignItemProperty GetProperty(DependencyProperty dependencyProperty)
{
if (dependencyProperty == null)
throw new ArgumentNullException("dependencyProperty");
return GetProperty(dependencyProperty.Name);
}
/// <summary>
/// Gets the design item property representing the specified attached dependency property.
/// </summary>
public DesignItemProperty GetAttachedProperty(DependencyProperty dependencyProperty)
{
if (dependencyProperty == null)
throw new ArgumentNullException("dependencyProperty");
return GetAttachedProperty(dependencyProperty.OwnerType, dependencyProperty.Name);
}
/// <summary>
/// Gets an enumerator to enumerate the properties that have a non-default value.

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/BehaviorExtension.cs

@ -14,7 +14,7 @@ namespace ICSharpCode.WpfDesign.Extensions @@ -14,7 +14,7 @@ namespace ICSharpCode.WpfDesign.Extensions
/// These extensions are always loaded. They must have an parameter-less constructor.
/// </summary>
[ExtensionServer(typeof(DefaultExtensionServer.Permanent))]
public abstract class BehaviorExtension : DefaultExtension
public class BehaviorExtension : DefaultExtension
{
}

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Extensions/ExtensionManager.cs

@ -123,7 +123,7 @@ namespace ICSharpCode.WpfDesign.Extensions @@ -123,7 +123,7 @@ namespace ICSharpCode.WpfDesign.Extensions
foreach (ExtensionEntry entry in GetExtensionEntries(item)) {
servers.Add(entry.Server);
}
return Linq.ToArray(servers);
return Func.ToArray(servers);
}
internal IEnumerable<Extension> CreateExtensions(ExtensionServer server, DesignItem item)

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Linq.cs → src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Func.cs

@ -11,7 +11,7 @@ using System.Collections.Generic; @@ -11,7 +11,7 @@ using System.Collections.Generic;
namespace ICSharpCode.WpfDesign
{
// Static helpers that should become extension methods in the future
static class Linq
static class Func
{
public static T[] ToArray<T>(ICollection<T> collection) where T : class
{

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataSource.cs

@ -39,7 +39,7 @@ namespace ICSharpCode.WpfDesign.PropertyEditor @@ -39,7 +39,7 @@ namespace ICSharpCode.WpfDesign.PropertyEditor
}
designItemProperties.AddRange(item.Properties);
foreach (DesignItemProperty p in Linq.Distinct(designItemProperties)) {
foreach (DesignItemProperty p in Func.Distinct(designItemProperties)) {
properties.Add(new DesignItemDataProperty(this, p));
}
}

4
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultiSelectionDataSource.cs

@ -13,7 +13,7 @@ namespace ICSharpCode.WpfDesign.PropertyEditor @@ -13,7 +13,7 @@ namespace ICSharpCode.WpfDesign.PropertyEditor
/// <summary>
/// Implements IPropertyEditorDataSource by combining the information from multiple data sources.
/// </summary>
public class MultiSelectionDataSource : IPropertyEditorDataSource
public sealed class MultiSelectionDataSource : IPropertyEditorDataSource
{
/// <summary>
/// Creates a data source for a collection of data sources.
@ -52,7 +52,7 @@ namespace ICSharpCode.WpfDesign.PropertyEditor @@ -52,7 +52,7 @@ namespace ICSharpCode.WpfDesign.PropertyEditor
this.services = services;
if (sources == null)
throw new ArgumentNullException("sources");
data = Linq.ToArray(sources);
data = Func.ToArray(sources);
if (data.Length < 2)
throw new ArgumentException("The collection must have at least 2 items!");

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/PropertyEditorBindingHelper.cs

@ -117,6 +117,8 @@ namespace ICSharpCode.WpfDesign.PropertyEditor @@ -117,6 +117,8 @@ namespace ICSharpCode.WpfDesign.PropertyEditor
}
}
// Used by the Binding using Reflection.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public object BoundValue {
get { return dataProperty.Value; }
set { dataProperty.Value = value; }

2
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj

@ -81,7 +81,7 @@ @@ -81,7 +81,7 @@
<Compile Include="Extensions\LogicalExtensionServers.cs" />
<Compile Include="Extensions\SelectionExtensionServer.cs" />
<Compile Include="HashSet.cs" />
<Compile Include="Linq.cs" />
<Compile Include="Func.cs" />
<Compile Include="PropertyEditor\BooleanEditor.cs" />
<Compile Include="PropertyEditor\MultiSelectionDataProperty.cs" />
<Compile Include="PropertyEditor\StandardValuesComboBoxEditor.cs" />

Loading…
Cancel
Save