bugfixes when content property is used in property mode

This commit is contained in:
jkuehner 2017-09-05 00:41:44 +02:00
Родитель d07893f2ad
Коммит 9b17211b1a
11 изменённых файлов: 1091 добавлений и 956 удалений

Просмотреть файл

@ -1,386 +1,386 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml;
using ICSharpCode.WpfDesign.Designer.Xaml;
using ICSharpCode.WpfDesign.Designer.Services;
using ICSharpCode.WpfDesign.Designer.Controls;
using System.Diagnostics;
namespace ICSharpCode.WpfDesign.Designer
{
/// <summary>
/// Surface hosting the WPF designer.
/// </summary>
[TemplatePart(Name = "PART_DesignContent", Type = typeof(ContentControl))]
[TemplatePart(Name = "PART_Zoom", Type = typeof(ZoomControl))]
public partial class DesignSurface : ContentControl, INotifyPropertyChanged
{
private FocusNavigator _focusNav;
static DesignSurface()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DesignSurface), new FrameworkPropertyMetadata(typeof(DesignSurface)));
}
public DesignSurface()
{
//Propertygrid should show no inherited Datacontext!
this.DataContext = null;
this.AddCommandHandler(ApplicationCommands.Undo, Undo, CanUndo);
this.AddCommandHandler(ApplicationCommands.Redo, Redo, CanRedo);
this.AddCommandHandler(ApplicationCommands.Copy, Copy, CanCopyOrCut);
this.AddCommandHandler(ApplicationCommands.Cut, Cut, CanCopyOrCut);
this.AddCommandHandler(ApplicationCommands.Delete, Delete, CanDelete);
this.AddCommandHandler(ApplicationCommands.Paste, Paste, CanPaste);
this.AddCommandHandler(ApplicationCommands.SelectAll, SelectAll, CanSelectAll);
this.AddCommandHandler(Commands.AlignTopCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Top), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignMiddleCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.VerticalMiddle), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignBottomCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Bottom), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignLeftCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Left), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignCenterCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.HorizontalMiddle), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignRightCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Right), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.RotateLeftCommand, () => ModelTools.ApplyTransform(this.DesignContext.Services.Selection.PrimarySelection, new RotateTransform(-90)), () => this.DesignContext.Services.Selection.PrimarySelection != null);
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Xml;
using ICSharpCode.WpfDesign.Designer.Xaml;
using ICSharpCode.WpfDesign.Designer.Services;
using ICSharpCode.WpfDesign.Designer.Controls;
using System.Diagnostics;
namespace ICSharpCode.WpfDesign.Designer
{
/// <summary>
/// Surface hosting the WPF designer.
/// </summary>
[TemplatePart(Name = "PART_DesignContent", Type = typeof(ContentControl))]
[TemplatePart(Name = "PART_Zoom", Type = typeof(ZoomControl))]
public partial class DesignSurface : ContentControl, INotifyPropertyChanged
{
private FocusNavigator _focusNav;
static DesignSurface()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(DesignSurface), new FrameworkPropertyMetadata(typeof(DesignSurface)));
}
public DesignSurface()
{
//Propertygrid should show no inherited Datacontext!
this.DataContext = null;
this.AddCommandHandler(ApplicationCommands.Undo, Undo, CanUndo);
this.AddCommandHandler(ApplicationCommands.Redo, Redo, CanRedo);
this.AddCommandHandler(ApplicationCommands.Copy, Copy, CanCopyOrCut);
this.AddCommandHandler(ApplicationCommands.Cut, Cut, CanCopyOrCut);
this.AddCommandHandler(ApplicationCommands.Delete, Delete, CanDelete);
this.AddCommandHandler(ApplicationCommands.Paste, Paste, CanPaste);
this.AddCommandHandler(ApplicationCommands.SelectAll, SelectAll, CanSelectAll);
this.AddCommandHandler(Commands.AlignTopCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Top), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignMiddleCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.VerticalMiddle), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignBottomCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Bottom), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignLeftCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Left), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignCenterCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.HorizontalMiddle), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.AlignRightCommand, () => ModelTools.ArrangeItems(this.DesignContext.Services.Selection.SelectedItems, ArrangeDirection.Right), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.RotateLeftCommand, () => ModelTools.ApplyTransform(this.DesignContext.Services.Selection.PrimarySelection, new RotateTransform(-90)), () => this.DesignContext.Services.Selection.PrimarySelection != null);
this.AddCommandHandler(Commands.RotateRightCommand, () => ModelTools.ApplyTransform(this.DesignContext.Services.Selection.PrimarySelection, new RotateTransform(90)), () => this.DesignContext.Services.Selection.PrimarySelection != null);
this.AddCommandHandler(Commands.StretchToSameWidthCommand, () => ModelTools.StretchItems(this.DesignContext.Services.Selection.SelectedItems, StretchDirection.Width), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.StretchToSameWidthCommand, () => ModelTools.StretchItems(this.DesignContext.Services.Selection.SelectedItems, StretchDirection.Width), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
this.AddCommandHandler(Commands.StretchToSameHeightCommand, () => ModelTools.StretchItems(this.DesignContext.Services.Selection.SelectedItems, StretchDirection.Height), () => this.DesignContext.Services.Selection.SelectedItems.Count() > 1);
_sceneContainer = new Border() { AllowDrop = false, UseLayoutRounding = true };
_sceneContainer.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Ideal);
_designPanel = new DesignPanel() {Child = _sceneContainer, DesignSurface = this};
}
internal DesignPanel _designPanel;
private ContentControl _partDesignContent;
private Border _sceneContainer;
public override void OnApplyTemplate()
{
_partDesignContent = this.Template.FindName("PART_DesignContent", this) as ContentControl;
_partDesignContent.Content = _designPanel;
_partDesignContent.RequestBringIntoView += _partDesignContent_RequestBringIntoView;
this.ZoomControl = this.Template.FindName("PART_Zoom", this) as ZoomControl;
OnPropertyChanged("ZoomControl");
base.OnApplyTemplate();
}
private bool enableBringIntoView = false;
public void ScrollIntoView(DesignItem designItem)
{
enableBringIntoView = true;
LogicalTreeHelper.BringIntoView(designItem.View);
enableBringIntoView = false;
}
void _partDesignContent_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
if (!enableBringIntoView)
e.Handled = true;
enableBringIntoView = false;
}
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (ZoomControl != null && e.OriginalSource == ZoomControl)
{
UnselectAll();
}
Keyboard.Focus(this.DesignPanel);
}
public ZoomControl ZoomControl { get; private set; }
DesignContext _designContext;
/// <summary>
/// Gets the active design context.
/// </summary>
public DesignContext DesignContext {
get { return _designContext; }
}
/// <summary>
/// Gets the DesignPanel
/// </summary>
public DesignPanel DesignPanel {
get { return _designPanel; }
}
/// <summary>
/// Initializes the designer content from the specified XmlReader.
/// </summary>
public void LoadDesigner(XmlReader xamlReader, XamlLoadSettings loadSettings)
{
UnloadDesigner();
loadSettings = loadSettings ?? new XamlLoadSettings();
loadSettings.CustomServiceRegisterFunctions.Add(
context => context.Services.AddService(typeof(IDesignPanel), _designPanel));
InitializeDesigner(new XamlDesignContext(xamlReader, loadSettings));
}
/// <summary>
/// Saves the designer content into the specified XmlWriter.
/// </summary>
public void SaveDesigner(XmlWriter writer)
{
_designContext.Save(writer);
}
void InitializeDesigner(DesignContext context)
{
_designContext = context;
_designPanel.Context = context;
_designPanel.ClearContextMenu();
if (context.RootItem != null) {
_sceneContainer.Child = context.RootItem.View;
}
context.Services.RunWhenAvailable<UndoService>(
undoService => undoService.UndoStackChanged += delegate {
CommandManager.InvalidateRequerySuggested();
}
);
context.Services.Selection.SelectionChanged += delegate {
CommandManager.InvalidateRequerySuggested();
};
context.Services.AddService(typeof(IKeyBindingService), new DesignerKeyBindings(this));
_focusNav=new FocusNavigator(this);
_focusNav.Start();
OnPropertyChanged("DesignContext");
}
/// <summary>
/// Unloads the designer content.
/// </summary>
public void UnloadDesigner()
{
if (_designContext != null) {
foreach (object o in _designContext.Services.AllServices) {
IDisposable d = o as IDisposable;
if (d != null) d.Dispose();
}
}
_designContext = null;
_designPanel.Context = null;
_sceneContainer.Child = null;
_designPanel.Adorners.Clear();
}
#region Commands
public bool CanUndo()
{
UndoService undoService = GetService<UndoService>();
return undoService != null && undoService.CanUndo;
}
public void Undo()
{
UndoService undoService = GetService<UndoService>();
IUndoAction action = undoService.UndoActions.First();
Debug.WriteLine("Undo " + action.Title);
undoService.Undo();
_designContext.Services.Selection.SetSelectedComponents(GetLiveElements(action.AffectedElements));
}
public bool CanRedo()
{
UndoService undoService = GetService<UndoService>();
return undoService != null && undoService.CanRedo;
}
public void Redo()
{
UndoService undoService = GetService<UndoService>();
IUndoAction action = undoService.RedoActions.First();
Debug.WriteLine("Redo " + action.Title);
undoService.Redo();
_designContext.Services.Selection.SetSelectedComponents(GetLiveElements(action.AffectedElements));
}
public bool CanCopyOrCut()
{
ISelectionService selectionService = GetService<ISelectionService>();
if(selectionService!=null){
if (selectionService.SelectedItems.Count == 0)
return false;
if (selectionService.SelectedItems.Count == 1 && selectionService.PrimarySelection == DesignContext.RootItem)
return false;
}
return true;
}
public void Copy()
{
XamlDesignContext xamlContext = _designContext as XamlDesignContext;
ISelectionService selectionService = GetService<ISelectionService>();
if(xamlContext != null && selectionService != null){
xamlContext.XamlEditAction.Copy(selectionService.SelectedItems);
}
}
public void Cut()
{
XamlDesignContext xamlContext = _designContext as XamlDesignContext;
ISelectionService selectionService = GetService<ISelectionService>();
if(xamlContext != null && selectionService != null){
xamlContext.XamlEditAction.Cut(selectionService.SelectedItems);
}
}
public bool CanDelete()
{
if (_designContext != null) {
return ModelTools.CanDeleteComponents(_designContext.Services.Selection.SelectedItems);
}
return false;
}
public void Delete()
{
if (_designContext != null) {
ModelTools.DeleteComponents(_designContext.Services.Selection.SelectedItems);
}
}
public bool CanPaste()
{
ISelectionService selectionService = GetService<ISelectionService>();
if (selectionService != null && selectionService.SelectedItems.Count != 0) {
try {
string xaml = Clipboard.GetText(TextDataFormat.Xaml);
if (xaml != "" && xaml != " ")
return true;
}
catch (Exception) {
}
}
return false;
}
public void Paste()
{
XamlDesignContext xamlContext = _designContext as XamlDesignContext;
if(xamlContext != null){
xamlContext.XamlEditAction.Paste();
}
}
public bool CanSelectAll()
{
return DesignContext != null;
}
//TODO: Do not select layout root
public void SelectAll()
{
var items = Descendants(DesignContext.RootItem).Where(item => ModelTools.CanSelectComponent(item)).ToArray();
DesignContext.Services.Selection.SetSelectedComponents(items);
}
public void UnselectAll()
{
DesignContext.Services.Selection.SetSelectedComponents(null);
}
//TODO: Share with Outline / PlacementBehavior
public static IEnumerable<DesignItem> DescendantsAndSelf(DesignItem item)
{
yield return item;
foreach (var child in Descendants(item)) {
yield return child;
}
}
public static IEnumerable<DesignItem> Descendants(DesignItem item)
{
if (item.ContentPropertyName != null) {
var content = item.ContentProperty;
if (content.IsCollection) {
foreach (var child in content.CollectionElements) {
foreach (var child2 in DescendantsAndSelf(child)) {
yield return child2;
}
}
} else {
if (content.Value != null) {
foreach (var child2 in DescendantsAndSelf(content.Value)) {
yield return child2;
}
}
}
}
}
// Filters an element list, dropping all elements that are not part of the xaml document
// (e.g. because they were deleted).
static List<DesignItem> GetLiveElements(ICollection<DesignItem> items)
{
List<DesignItem> result = new List<DesignItem>(items.Count);
foreach (DesignItem item in items) {
if (ModelTools.IsInDocument(item) && ModelTools.CanSelectComponent(item)) {
result.Add(item);
}
}
return result;
}
T GetService<T>() where T : class
{
if (_designContext != null)
return _designContext.Services.GetService<T>();
else
return null;
}
#endregion
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var ev = PropertyChanged;
if (ev != null)
ev(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}
_sceneContainer = new Border() { AllowDrop = false, UseLayoutRounding = true };
_sceneContainer.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Ideal);
_designPanel = new DesignPanel() {Child = _sceneContainer, DesignSurface = this};
}
internal DesignPanel _designPanel;
private ContentControl _partDesignContent;
private Border _sceneContainer;
public override void OnApplyTemplate()
{
_partDesignContent = this.Template.FindName("PART_DesignContent", this) as ContentControl;
_partDesignContent.Content = _designPanel;
_partDesignContent.RequestBringIntoView += _partDesignContent_RequestBringIntoView;
this.ZoomControl = this.Template.FindName("PART_Zoom", this) as ZoomControl;
OnPropertyChanged("ZoomControl");
base.OnApplyTemplate();
}
private bool enableBringIntoView = false;
public void ScrollIntoView(DesignItem designItem)
{
enableBringIntoView = true;
LogicalTreeHelper.BringIntoView(designItem.View);
enableBringIntoView = false;
}
void _partDesignContent_RequestBringIntoView(object sender, RequestBringIntoViewEventArgs e)
{
if (!enableBringIntoView)
e.Handled = true;
enableBringIntoView = false;
}
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (ZoomControl != null && e.OriginalSource == ZoomControl)
{
UnselectAll();
}
Keyboard.Focus(this.DesignPanel);
}
public ZoomControl ZoomControl { get; private set; }
DesignContext _designContext;
/// <summary>
/// Gets the active design context.
/// </summary>
public DesignContext DesignContext {
get { return _designContext; }
}
/// <summary>
/// Gets the DesignPanel
/// </summary>
public DesignPanel DesignPanel {
get { return _designPanel; }
}
/// <summary>
/// Initializes the designer content from the specified XmlReader.
/// </summary>
public void LoadDesigner(XmlReader xamlReader, XamlLoadSettings loadSettings)
{
UnloadDesigner();
loadSettings = loadSettings ?? new XamlLoadSettings();
loadSettings.CustomServiceRegisterFunctions.Add(
context => context.Services.AddService(typeof(IDesignPanel), _designPanel));
InitializeDesigner(new XamlDesignContext(xamlReader, loadSettings));
}
/// <summary>
/// Saves the designer content into the specified XmlWriter.
/// </summary>
public void SaveDesigner(XmlWriter writer)
{
_designContext.Save(writer);
}
void InitializeDesigner(DesignContext context)
{
_designContext = context;
_designPanel.Context = context;
_designPanel.ClearContextMenu();
if (context.RootItem != null) {
_sceneContainer.Child = context.RootItem.View;
}
context.Services.RunWhenAvailable<UndoService>(
undoService => undoService.UndoStackChanged += delegate {
CommandManager.InvalidateRequerySuggested();
}
);
context.Services.Selection.SelectionChanged += delegate {
CommandManager.InvalidateRequerySuggested();
};
context.Services.AddService(typeof(IKeyBindingService), new DesignerKeyBindings(this));
_focusNav=new FocusNavigator(this);
_focusNav.Start();
OnPropertyChanged("DesignContext");
}
/// <summary>
/// Unloads the designer content.
/// </summary>
public void UnloadDesigner()
{
if (_designContext != null) {
foreach (object o in _designContext.Services.AllServices) {
IDisposable d = o as IDisposable;
if (d != null) d.Dispose();
}
}
_designContext = null;
_designPanel.Context = null;
_sceneContainer.Child = null;
_designPanel.Adorners.Clear();
}
#region Commands
public bool CanUndo()
{
UndoService undoService = GetService<UndoService>();
return undoService != null && undoService.CanUndo;
}
public void Undo()
{
UndoService undoService = GetService<UndoService>();
IUndoAction action = undoService.UndoActions.First();
Debug.WriteLine("Undo " + action.Title);
undoService.Undo();
_designContext.Services.Selection.SetSelectedComponents(GetLiveElements(action.AffectedElements));
}
public bool CanRedo()
{
UndoService undoService = GetService<UndoService>();
return undoService != null && undoService.CanRedo;
}
public void Redo()
{
UndoService undoService = GetService<UndoService>();
IUndoAction action = undoService.RedoActions.First();
Debug.WriteLine("Redo " + action.Title);
undoService.Redo();
_designContext.Services.Selection.SetSelectedComponents(GetLiveElements(action.AffectedElements));
}
public bool CanCopyOrCut()
{
ISelectionService selectionService = GetService<ISelectionService>();
if(selectionService!=null){
if (selectionService.SelectedItems.Count == 0)
return false;
if (selectionService.SelectedItems.Count == 1 && selectionService.PrimarySelection == DesignContext.RootItem)
return false;
}
return true;
}
public void Copy()
{
XamlDesignContext xamlContext = _designContext as XamlDesignContext;
ISelectionService selectionService = GetService<ISelectionService>();
if(xamlContext != null && selectionService != null){
xamlContext.XamlEditAction.Copy(selectionService.SelectedItems);
}
}
public void Cut()
{
XamlDesignContext xamlContext = _designContext as XamlDesignContext;
ISelectionService selectionService = GetService<ISelectionService>();
if(xamlContext != null && selectionService != null){
xamlContext.XamlEditAction.Cut(selectionService.SelectedItems);
}
}
public bool CanDelete()
{
if (_designContext != null) {
return ModelTools.CanDeleteComponents(_designContext.Services.Selection.SelectedItems);
}
return false;
}
public void Delete()
{
if (_designContext != null) {
ModelTools.DeleteComponents(_designContext.Services.Selection.SelectedItems);
}
}
public bool CanPaste()
{
ISelectionService selectionService = GetService<ISelectionService>();
if (selectionService != null && selectionService.SelectedItems.Count != 0) {
try {
string xaml = Clipboard.GetText(TextDataFormat.Xaml);
if (xaml != "" && xaml != " ")
return true;
}
catch (Exception) {
}
}
return false;
}
public void Paste()
{
XamlDesignContext xamlContext = _designContext as XamlDesignContext;
if(xamlContext != null){
xamlContext.XamlEditAction.Paste();
}
}
public bool CanSelectAll()
{
return DesignContext != null;
}
//TODO: Do not select layout root
public void SelectAll()
{
var items = Descendants(DesignContext.RootItem).Where(item => ModelTools.CanSelectComponent(item)).ToArray();
DesignContext.Services.Selection.SetSelectedComponents(items);
}
public void UnselectAll()
{
DesignContext.Services.Selection.SetSelectedComponents(null);
}
//TODO: Share with Outline / PlacementBehavior
public static IEnumerable<DesignItem> DescendantsAndSelf(DesignItem item)
{
yield return item;
foreach (var child in Descendants(item)) {
yield return child;
}
}
public static IEnumerable<DesignItem> Descendants(DesignItem item)
{
if (item.ContentPropertyName != null) {
var content = item.ContentProperty;
if (content.IsCollection) {
foreach (var child in content.CollectionElements) {
foreach (var child2 in DescendantsAndSelf(child)) {
yield return child2;
}
}
} else {
if (content.Value != null) {
foreach (var child2 in DescendantsAndSelf(content.Value)) {
yield return child2;
}
}
}
}
}
// Filters an element list, dropping all elements that are not part of the xaml document
// (e.g. because they were deleted).
static List<DesignItem> GetLiveElements(ICollection<DesignItem> items)
{
List<DesignItem> result = new List<DesignItem>(items.Count);
foreach (DesignItem item in items) {
if (ModelTools.IsInDocument(item) && ModelTools.CanSelectComponent(item)) {
result.Add(item);
}
}
return result;
}
T GetService<T>() where T : class
{
if (_designContext != null)
return _designContext.Services.GetService<T>();
else
return null;
}
#endregion
#region INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged(string propertyName)
{
var ev = PropertyChanged;
if (ev != null)
ev(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
}

Просмотреть файл

@ -24,7 +24,7 @@ using ICSharpCode.WpfDesign.Extensions;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
[ExtensionServer(typeof(PrimarySelectionExtensionServer))]
[ExtensionFor(typeof (UIElement))]
[ExtensionFor(typeof(object))]
[Extension(Order = 10)]
public class DefaultCommandsContextMenuExtension : SelectionAdornerProvider
{

Просмотреть файл

@ -1,21 +1,21 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
@ -40,8 +40,8 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
protected override void OnInitialized()
{
base.OnInitialized();
if (ExtendedItem.ContentProperty == null ||
Metadata.IsPlacementDisabled(ExtendedItem.ComponentType))
if (ExtendedItem.ContentProperty == null ||
Metadata.IsPlacementDisabled(ExtendedItem.ComponentType))
return;
ExtendedItem.AddBehavior(typeof(IPlacementBehavior), this);
}
@ -85,13 +85,13 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public virtual void SetPosition(PlacementInformation info)
{
if (info.Operation.Type != PlacementType.Move
if (info.Operation.Type != PlacementType.Move
&& info.Operation.Type != PlacementType.MovePoint
&& info.Operation.Type != PlacementType.MoveAndIgnoreOtherContainers)
ModelTools.Resize(info.Item, info.Bounds.Width, info.Bounds.Height);
//if (info.Operation.Type == PlacementType.MovePoint)
// ModelTools.Resize(info.Item, info.Bounds.Width, info.Bounds.Height);
ModelTools.Resize(info.Item, info.Bounds.Width, info.Bounds.Height);
//if (info.Operation.Type == PlacementType.MovePoint)
// ModelTools.Resize(info.Item, info.Bounds.Width, info.Bounds.Height);
}
public virtual bool CanLeaveContainer(PlacementOperation operation)
@ -101,76 +101,86 @@ namespace ICSharpCode.WpfDesign.Designer.Extensions
public virtual void LeaveContainer(PlacementOperation operation)
{
if (ExtendedItem.ContentProperty.IsCollection) {
foreach (var info in operation.PlacedItems) {
if (ExtendedItem.ContentProperty.IsCollection)
{
foreach (var info in operation.PlacedItems)
{
ExtendedItem.ContentProperty.CollectionElements.Remove(info.Item);
}
} else {
}
else
{
ExtendedItem.ContentProperty.Reset();
}
}
private static InfoTextEnterArea infoTextEnterArea;
private static InfoTextEnterArea infoTextEnterArea;
public virtual bool CanEnterContainer(PlacementOperation operation, bool shouldAlwaysEnter)
{
var canEnter = internalCanEnterContainer(operation);
var canEnter = internalCanEnterContainer(operation);
if (canEnter && !shouldAlwaysEnter && !Keyboard.IsKeyDown(Key.LeftAlt) && !Keyboard.IsKeyDown(Key.RightAlt))
{
var b = new Rect(0, 0, ((FrameworkElement)this.ExtendedItem.View).ActualWidth, ((FrameworkElement)this.ExtendedItem.View).ActualHeight);
InfoTextEnterArea.Start(ref infoTextEnterArea, this.Services, this.ExtendedItem.View, b, Translations.Instance.PressAltText);
InfoTextEnterArea.Start(ref infoTextEnterArea, this.Services, this.ExtendedItem.View, b, Translations.Instance.PressAltText);
return false;
}
}
return canEnter;
}
}
private bool internalCanEnterContainer(PlacementOperation operation)
{
InfoTextEnterArea.Stop(ref infoTextEnterArea);
InfoTextEnterArea.Stop(ref infoTextEnterArea);
if (ExtendedItem.Component is Expander)
{
if (!((Expander) ExtendedItem.Component).IsExpanded)
if (!((Expander)ExtendedItem.Component).IsExpanded)
{
((Expander) ExtendedItem.Component).IsExpanded = true;
((Expander)ExtendedItem.Component).IsExpanded = true;
}
}
if (ExtendedItem.Component is UserControl && ExtendedItem.ComponentType != typeof(UserControl))
return false;
return false;
if (ExtendedItem.Component is Decorator)
return ((Decorator)ExtendedItem.Component).Child == null;
return ((Decorator)ExtendedItem.Component).Child == null;
if (ExtendedItem.ContentProperty.IsCollection)
return CollectionSupport.CanCollectionAdd(ExtendedItem.ContentProperty.ReturnType,
operation.PlacedItems.Select(p => p.Item.Component));
return CollectionSupport.CanCollectionAdd(ExtendedItem.ContentProperty.ReturnType,
operation.PlacedItems.Select(p => p.Item.Component));
if (ExtendedItem.ContentProperty.ReturnType == typeof(string))
return false;
if (!ExtendedItem.ContentProperty.IsSet)
return true;
object value = ExtendedItem.ContentProperty.ValueOnInstance;
// don't overwrite non-primitive values like bindings
return true;
object value = ExtendedItem.ContentProperty.ValueOnInstance;
// don't overwrite non-primitive values like bindings
return ExtendedItem.ContentProperty.Value == null && (value is string && string.IsNullOrEmpty(value as string));
}
public virtual void EnterContainer(PlacementOperation operation)
{
if (ExtendedItem.ContentProperty.IsCollection) {
foreach (var info in operation.PlacedItems) {
if (ExtendedItem.ContentProperty.IsCollection)
{
foreach (var info in operation.PlacedItems)
{
ExtendedItem.ContentProperty.CollectionElements.Add(info.Item);
}
} else {
}
else
{
ExtendedItem.ContentProperty.SetValue(operation.PlacedItems[0].Item);
}
if (operation.Type == PlacementType.AddItem) {
foreach (var info in operation.PlacedItems) {
if (operation.Type == PlacementType.AddItem)
{
foreach (var info in operation.PlacedItems)
{
SetPosition(info);
}
}

Просмотреть файл

@ -0,0 +1,111 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Collections.Generic;
using ICSharpCode.WpfDesign.Extensions;
using System.Windows.Controls;
using System.Windows;
using ICSharpCode.WpfDesign.Designer.Controls;
namespace ICSharpCode.WpfDesign.Designer.Extensions
{
[ExtensionFor(typeof(object))]
public class OnlyDeletePlacementBehavior : BehaviorExtension, IPlacementBehavior
{
static OnlyDeletePlacementBehavior()
{ }
protected override void OnInitialized()
{
base.OnInitialized();
if (ExtendedItem.Component is Panel || ExtendedItem.Component is Control || ExtendedItem.Component is Border || ExtendedItem.Component is Viewbox)
return;
ExtendedItem.AddBehavior(typeof(IPlacementBehavior), this);
}
public virtual bool CanPlace(IEnumerable<DesignItem> childItems, PlacementType type, PlacementAlignment position)
{
return type == PlacementType.Delete;
}
public virtual void BeginPlacement(PlacementOperation operation)
{
}
public virtual void EndPlacement(PlacementOperation operation)
{
}
public virtual Rect GetPosition(PlacementOperation operation, DesignItem item)
{
return new Rect();
}
public Rect GetPositionRelativeToContainer(PlacementOperation operation, DesignItem item)
{
return new Rect();
}
public virtual void BeforeSetPosition(PlacementOperation operation)
{
}
public virtual bool CanPlaceItem(PlacementInformation info)
{
return false;
}
public virtual void SetPosition(PlacementInformation info)
{
}
public virtual bool CanLeaveContainer(PlacementOperation operation)
{
return true;
}
public virtual void LeaveContainer(PlacementOperation operation)
{
foreach (var item in operation.PlacedItems) {
if (item.Item.ParentProperty.IsCollection) {
item.Item.ParentProperty.CollectionElements.Remove(item.Item);
}
else {
item.Item.ParentProperty.Reset();
}
}
}
private static InfoTextEnterArea infoTextEnterArea;
public virtual bool CanEnterContainer(PlacementOperation operation, bool shouldAlwaysEnter)
{
return false;
}
public virtual void EnterContainer(PlacementOperation operation)
{
}
public virtual Point PlacePoint(Point point)
{
return new Point();
}
}
}

Просмотреть файл

@ -4,9 +4,8 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Default="clr-namespace:ICSharpCode.WpfDesign.Designer.OutlineView"
xmlns:Controls="clr-namespace:ICSharpCode.WpfDesign.Designer.Controls">
<UserControl.Resources>
<Style TargetType="ToggleButton" x:Key="eyeStyle">
<Setter Property="Template">
<Setter.Value>
@ -73,8 +72,8 @@
<HierarchicalDataTemplate DataType="{x:Type Default:OutlineNode}"
ItemsSource="{Binding Children}">
<DockPanel>
<ToggleButton Style="{StaticResource lockedStyle}" DockPanel.Dock="Right" Width="20" Margin="0,0,5,0" IsChecked="{Binding IsDesignTimeLocked}" />
<ToggleButton Style="{StaticResource eyeStyle}" DockPanel.Dock="Right" Width="20" Margin="0,0,5,0" IsChecked="{Binding IsDesignTimeVisible}" />
<ToggleButton Visibility="{Binding IsVisualNode}" Style="{StaticResource lockedStyle}" DockPanel.Dock="Right" Width="20" Margin="0,0,5,0" IsChecked="{Binding IsDesignTimeLocked}" />
<ToggleButton Visibility="{Binding IsVisualNode}" Style="{StaticResource eyeStyle}" DockPanel.Dock="Right" Width="20" Margin="0,0,5,0" IsChecked="{Binding IsDesignTimeVisible}" />
<Default:IconItem Icon="../Images/Tag.png" Text="{Binding Name}" />
</DockPanel>
</HierarchicalDataTemplate>

Просмотреть файл

@ -1,128 +1,146 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
namespace ICSharpCode.WpfDesign.Designer.OutlineView
{
public class OutlineNode: OutlineNodeBase
{
//TODO: Reset with DesignContext
static Dictionary<DesignItem, IOutlineNode> outlineNodes = new Dictionary<DesignItem, IOutlineNode>();
protected OutlineNode(DesignItem designitem): base(designitem)
{
UpdateChildren();
SelectionService.SelectionChanged += new EventHandler<DesignItemCollectionEventArgs>(Selection_SelectionChanged);
}
protected OutlineNode(string name) : base(name)
{
}
static OutlineNode()
{
DummyPlacementType = PlacementType.Register("DummyPlacement");
}
public static IOutlineNode Create(DesignItem designItem)
{
IOutlineNode node = null;
if (designItem != null && !outlineNodes.TryGetValue(designItem, out node)) {
node = new OutlineNode(designItem);
outlineNodes[designItem] = node;
}
return node;
}
void Selection_SelectionChanged(object sender, DesignItemCollectionEventArgs e)
{
IsSelected = DesignItem.Services.Selection.IsComponentSelected(DesignItem);
}
protected override void UpdateChildren()
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.Designer.OutlineView
{
public class OutlineNode: OutlineNodeBase
{
//TODO: Reset with DesignContext
static Dictionary<DesignItem, IOutlineNode> outlineNodes = new Dictionary<DesignItem, IOutlineNode>();
protected OutlineNode(DesignItem designitem): base(designitem)
{
Children.Clear();
foreach (var prp in DesignItem.AllSetProperties) {
if (prp.Name != DesignItem.ContentPropertyName) {
if (prp.Value != null) {
var propertyNode = PropertyOutlineNode.Create(prp.Name);
var node = OutlineNode.Create(prp.Value);
propertyNode.Children.Add(node);
Children.Add(propertyNode);
}
}
}
if (DesignItem.ContentPropertyName != null) {
var content = DesignItem.ContentProperty;
if (content.IsCollection) {
UpdateChildrenCore(content.CollectionElements);
} else {
if (content.Value != null) {
UpdateChildrenCore(new[] { content.Value });
}
}
UpdateChildren();
SelectionService.SelectionChanged += new EventHandler<DesignItemCollectionEventArgs>(Selection_SelectionChanged);
}
protected OutlineNode(string name) : base(name)
{
}
static OutlineNode()
{
DummyPlacementType = PlacementType.Register("DummyPlacement");
}
public static IOutlineNode Create(DesignItem designItem)
{
IOutlineNode node = null;
if (designItem != null && !outlineNodes.TryGetValue(designItem, out node)) {
node = new OutlineNode(designItem);
outlineNodes[designItem] = node;
}
}
protected override void UpdateChildrenCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Remove) {
foreach (var oldItem in e.OldItems) {
var item = Children.FirstOrDefault(x => x.DesignItem == oldItem);
if (item != null) {
Children.Remove(item);
}
}
} else if (e.Action == NotifyCollectionChangedAction.Add) {
UpdateChildrenCore(e.NewItems.Cast<DesignItem>(), e.NewStartingIndex);
}
}
void UpdateChildrenCore(IEnumerable<DesignItem> items, int index = -1)
{
foreach (var item in items) {
if (ModelTools.CanSelectComponent(item)) {
if (Children.All(x => x.DesignItem != item)) {
var node = OutlineNode.Create(item);
if (index>-1)
Children.Insert(index++, node);
else
Children.Add(node);
}
} else {
var content = item.ContentProperty;
if (content != null) {
if (content.IsCollection) {
UpdateChildrenCore(content.CollectionElements);
} else {
if (content.Value != null) {
UpdateChildrenCore(new[] { content.Value });
}
}
}
}
}
}
}
}
return node;
}
void Selection_SelectionChanged(object sender, DesignItemCollectionEventArgs e)
{
IsSelected = DesignItem.Services.Selection.IsComponentSelected(DesignItem);
}
protected override void UpdateChildren()
{
Children.Clear();
foreach (var prp in DesignItem.AllSetProperties) {
if (prp.Name != DesignItem.ContentPropertyName)
{
if (prp.Value != null) {
var propertyNode = PropertyOutlineNode.Create(prp.Name);
var node = OutlineNode.Create(prp.Value);
propertyNode.Children.Add(node);
Children.Add(propertyNode);
}
}
}
if (DesignItem.ContentPropertyName != null) {
var content = DesignItem.ContentProperty;
if (content.IsCollection) {
UpdateChildrenCore(content.CollectionElements);
} else {
if (content.Value != null) {
if (!UpdateChildrenCore(new[] {content.Value})) {
var propertyNode = PropertyOutlineNode.Create(content.Name);
var node = OutlineNode.Create(content.Value);
propertyNode.Children.Add(node);
Children.Add(propertyNode);
}
}
}
}
}
protected override void UpdateChildrenCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Remove) {
foreach (var oldItem in e.OldItems) {
var item = Children.FirstOrDefault(x => x.DesignItem == oldItem);
if (item != null) {
Children.Remove(item);
}
}
} else if (e.Action == NotifyCollectionChangedAction.Add) {
UpdateChildrenCore(e.NewItems.Cast<DesignItem>(), e.NewStartingIndex);
}
}
bool UpdateChildrenCore(IEnumerable<DesignItem> items, int index = -1)
{
var retVal = false;
foreach (var item in items) {
if (ModelTools.CanSelectComponent(item)) {
if (Children.All(x => x.DesignItem != item)) {
var node = OutlineNode.Create(item);
if (index > -1) {
Children.Insert(index++, node);
retVal = true;
}
else {
Children.Add(node);
retVal = true;
}
}
} else {
var content = item.ContentProperty;
if (content != null) {
if (content.IsCollection) {
UpdateChildrenCore(content.CollectionElements);
retVal = true;
} else {
if (content.Value != null) {
UpdateChildrenCore(new[] { content.Value });
retVal = true;
}
}
}
}
}
return retVal;
}
}
}

Просмотреть файл

@ -16,12 +16,14 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using ICSharpCode.WpfDesign.Designer.Xaml;
using ICSharpCode.WpfDesign.XamlDom;
@ -39,7 +41,12 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
private bool _collectionWasChanged;
private string _name;
private string _name;
public Visibility IsVisualNode
{
get { return this.DesignItem.Component is Visual ? Visibility.Visible : Visibility.Collapsed; }
}
protected OutlineNodeBase(DesignItem designItem)
{
@ -197,12 +204,12 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
void DesignItem_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == DesignItem.ContentPropertyName) {
//if (e.PropertyName == DesignItem.ContentPropertyName) {
if (!_collectionWasChanged) {
UpdateChildren();
}
_collectionWasChanged = false;
}
//}
}
private void CollectionElements_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
@ -211,8 +218,6 @@ namespace ICSharpCode.WpfDesign.Designer.OutlineView
UpdateChildrenCollectionChanged(e);
}
public bool CanInsert(IEnumerable<IOutlineNode> nodes, IOutlineNode after, bool copy)
{
var placementBehavior = DesignItem.GetBehavior<IPlacementBehavior>();

Просмотреть файл

@ -4,7 +4,7 @@
xmlns:Converters="clr-namespace:ICSharpCode.WpfDesign.Designer.Converters"
>
<Converters:LevelConverter x:Key="LevelConverter" />
<Style TargetType="{x:Type Default:IconItem}">
<Setter Property="Template">
<Setter.Value>
@ -20,7 +20,7 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ExpandButtonStyle"
TargetType="ToggleButton">
<Setter Property="Focusable"
@ -64,9 +64,9 @@
</Setter.Value>
</Setter>
</Style>
<Brush x:Key="InsertBrush">#FFC73C</Brush>
<Style TargetType="{x:Type Default:DragTreeView}">
<Setter Property="Template">
<Setter.Value>
@ -89,14 +89,14 @@
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type Default:DragTreeViewItem}">
<Setter Property="Foreground"
Value="{x:Static SystemColors.ControlTextBrush}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Default:DragTreeViewItem}">
<DockPanel Background="White" ContextMenu="{Binding DesignItem.Services.DesignPanel.ContextMenu}">
<Grid x:Name="bg"
Margin="{TemplateBinding Level, Converter={StaticResource LevelConverter}}"
@ -112,16 +112,7 @@
ContentSource="Header" />
</Border>
</Grid>
<ItemsPresenter x:Name="itemsHost" />
<!-- <DockPanel.ContextMenu>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Cut" />
<MenuItem Command="ApplicationCommands.Copy" />
<MenuItem Command="ApplicationCommands.Paste" />
<Separator />
<MenuItem Command="ApplicationCommands.Delete" />
</ContextMenu>
</DockPanel.ContextMenu>-->
<ItemsPresenter x:Name="itemsHost" />
<DockPanel.ToolTip>
<ToolTip Background="White">
<Rectangle Width="50" Height="50">
@ -132,7 +123,7 @@
</ToolTip>
</DockPanel.ToolTip>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsExpanded"
Value="False">

Просмотреть файл

@ -85,6 +85,7 @@
<Link>GlobalAssemblyInfo.cs</Link>
</Compile>
<Compile Include="Extensions\BorderForMouseOver.cs" />
<Compile Include="Extensions\OnlyDeletePlacementBehavior.cs" />
<Compile Include="OutlineView\PropertyOutlineNode.cs" />
<Compile Include="PropertyGrid\Editors\ColorEditor\ColorEditorPopup.xaml.cs">
<DependentUpon>ColorEditorPopup.xaml</DependentUpon>

Просмотреть файл

@ -125,7 +125,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
/// <param name="item"></param>
/// <param name="onlyFromSameNamescope"></param>
/// <returns></returns>
private XamlObject GetRootXamlObject(XamlObject item, bool onlyFromSameNamescope = false)
internal static XamlObject GetRootXamlObject(XamlObject item, bool onlyFromSameNamescope = false)
{
var root = item;
while (root.ParentObject != null)
@ -144,7 +144,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml
/// <param name="item"></param>
/// <param name="onlyFromSameNamescope"></param>
/// <returns></returns>
private IEnumerable<XamlObject> GetAllChildXamlObjects(XamlObject item, bool onlyFromSameNamescope = false)
internal static IEnumerable<XamlObject> GetAllChildXamlObjects(XamlObject item, bool onlyFromSameNamescope = false)
{
foreach (var prop in item.Properties)
{

Просмотреть файл

@ -1,363 +1,363 @@
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using ICSharpCode.WpfDesign.UIExtensions;
using ICSharpCode.WpfDesign.Extensions;
using System.Linq;
namespace ICSharpCode.WpfDesign
{
/// <summary>
/// The DesignItem connects a component with the service system and the designers.
/// Equivalent to Cider's ModelItem.
/// </summary>
public abstract class DesignItem : INotifyPropertyChanged
{
/// <summary>
/// Gets the component this DesignSite was created for.
/// </summary>
public abstract object Component { get; }
/// <summary>
/// Gets the component type of this design site.
/// This value may be different from Component.GetType() if a CustomInstanceFactory created
/// an object using a different type (e.g. ComponentType=Window but Component.GetType()=WindowClone).
/// </summary>
public abstract Type ComponentType { get; }
/// <summary>
/// Gets the view used for the component.
/// </summary>
public abstract UIElement View { get; }
/// <summary>
/// Set the View for a Component
/// </summary>
/// <param name="newView"></param>
public abstract void SetView(UIElement newView);
/// <summary>
/// Gets the design context.
/// </summary>
public abstract DesignContext Context { get; }
/// <summary>
/// Gets the parent design item.
/// </summary>
public abstract DesignItem Parent { get; }
/// <summary>
/// Occurs when the parent of this design item changes.
/// </summary>
public abstract event EventHandler ParentChanged;
/// <summary>
/// Gets the property where this DesignItem is used as a value.
/// </summary>
public abstract DesignItemProperty ParentProperty { get; }
/// <summary>
/// Gets properties set on the design item.
/// </summary>
public abstract DesignItemPropertyCollection Properties { get; }
/// <summary>
/// Gets properties set on the design item.
/// </summary>
public abstract IEnumerable<DesignItemProperty> AllSetProperties { get; }
/// <summary>
/// Gets/Sets the name of the design item.
/// </summary>
public abstract string Name { get; set; }
/// <summary>
/// Gets/Sets the value of the "x:Key" attribute on the design item.
/// </summary>
public abstract string Key { get; set; }
/// <summary>
/// Is raised when the name of the design item changes.
/// </summary>
public abstract event EventHandler NameChanged;
/// <summary>
/// Gets an instance that provides convenience properties for the most-used designers.
/// </summary>
public ServiceContainer Services {
[DebuggerStepThrough]
get { return this.Context.Services; }
}
/// <summary>
/// Opens a new change group used to batch several changes.
/// ChangeGroups work as transactions and are used to support the Undo/Redo system.
/// Note: the ChangeGroup applies to the whole <see cref="DesignContext"/>, not just to
/// this item!
/// </summary>
public ChangeGroup OpenGroup(string changeGroupTitle)
{
return this.Context.OpenGroup(changeGroupTitle, new DesignItem[] { this });
}
#region Extensions support
private struct ExtensionEntry
{
internal readonly Extension Extension;
internal readonly ExtensionServer Server;
public ExtensionEntry(Extension extension, ExtensionServer server)
{
this.Extension = extension;
this.Server = server;
}
}
ExtensionServer[] _extensionServers;
bool[] _extensionServerIsApplied;
List<ExtensionEntry> _extensions = new List<ExtensionEntry>();
/// <summary>
/// Gets the extensions registered for this DesignItem.
/// </summary>
public IEnumerable<Extension> Extensions {
get {
return _extensions.Select(x => x.Extension).ToList();
}
}
internal void SetExtensionServers(ExtensionManager extensionManager, ExtensionServer[] extensionServers)
{
Debug.Assert(_extensionServers == null);
Debug.Assert(extensionServers != null);
_extensionServers = extensionServers;
_extensionServerIsApplied = new bool[extensionServers.Length];
for (int i = 0; i < _extensionServers.Length; i++) {
bool shouldApply = _extensionServers[i].ShouldApplyExtensions(this);
if (shouldApply != _extensionServerIsApplied[i]) {
_extensionServerIsApplied[i] = shouldApply;
ApplyUnapplyExtensionServer(extensionManager, shouldApply, _extensionServers[i]);
}
}
}
internal void ReapplyExtensionServer(ExtensionManager extensionManager, ExtensionServer server)
{
Debug.Assert(_extensionServers != null);
for (int i = 0; i < _extensionServers.Length; i++) {
if (_extensionServers[i] == server) {
bool shouldApply = server.ShouldApplyExtensions(this);
if (server.ShouldBeReApplied() && shouldApply && shouldApply == _extensionServerIsApplied[i])
{
_extensionServerIsApplied[i] = false;
ApplyUnapplyExtensionServer(extensionManager, false, server);
}
if (shouldApply != _extensionServerIsApplied[i]) {
_extensionServerIsApplied[i] = shouldApply;
ApplyUnapplyExtensionServer(extensionManager, shouldApply, server);
}
}
}
}
private void ApplyUnapplyExtensionServer(ExtensionManager extensionManager, bool shouldApply, ExtensionServer server)
{
if (shouldApply) {
// add extensions
foreach (Extension ext in extensionManager.CreateExtensions(server, this)) {
_extensions.Add(new ExtensionEntry(ext, server));
}
} else {
// remove extensions
_extensions.RemoveAll(
delegate (ExtensionEntry entry) {
if (entry.Server == server) {
server.RemoveExtension(entry.Extension);
return true;
} else {
return false;
}
});
}
}
// Copyright (c) 2014 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using ICSharpCode.WpfDesign.UIExtensions;
using ICSharpCode.WpfDesign.Extensions;
using System.Linq;
namespace ICSharpCode.WpfDesign
{
/// <summary>
/// The DesignItem connects a component with the service system and the designers.
/// Equivalent to Cider's ModelItem.
/// </summary>
public abstract class DesignItem : INotifyPropertyChanged
{
/// <summary>
/// Gets the component this DesignSite was created for.
/// </summary>
public abstract object Component { get; }
/// <summary>
/// Gets the component type of this design site.
/// This value may be different from Component.GetType() if a CustomInstanceFactory created
/// an object using a different type (e.g. ComponentType=Window but Component.GetType()=WindowClone).
/// </summary>
public abstract Type ComponentType { get; }
/// <summary>
/// Gets the view used for the component.
/// </summary>
public abstract UIElement View { get; }
/// <summary>
/// Set the View for a Component
/// </summary>
/// <param name="newView"></param>
public abstract void SetView(UIElement newView);
/// <summary>
/// Gets the design context.
/// </summary>
public abstract DesignContext Context { get; }
/// <summary>
/// Gets the parent design item.
/// </summary>
public abstract DesignItem Parent { get; }
/// <summary>
/// Occurs when the parent of this design item changes.
/// </summary>
public abstract event EventHandler ParentChanged;
/// <summary>
/// Gets the property where this DesignItem is used as a value.
/// </summary>
public abstract DesignItemProperty ParentProperty { get; }
/// <summary>
/// Gets properties set on the design item.
/// </summary>
public abstract DesignItemPropertyCollection Properties { get; }
/// <summary>
/// Gets properties set on the design item.
/// </summary>
public abstract IEnumerable<DesignItemProperty> AllSetProperties { get; }
/// <summary>
/// Gets/Sets the name of the design item.
/// </summary>
public abstract string Name { get; set; }
/// <summary>
/// Gets/Sets the value of the "x:Key" attribute on the design item.
/// </summary>
public abstract string Key { get; set; }
/// <summary>
/// Is raised when the name of the design item changes.
/// </summary>
public abstract event EventHandler NameChanged;
/// <summary>
/// Gets an instance that provides convenience properties for the most-used designers.
/// </summary>
public ServiceContainer Services {
[DebuggerStepThrough]
get { return this.Context.Services; }
}
/// <summary>
/// Opens a new change group used to batch several changes.
/// ChangeGroups work as transactions and are used to support the Undo/Redo system.
/// Note: the ChangeGroup applies to the whole <see cref="DesignContext"/>, not just to
/// this item!
/// </summary>
public ChangeGroup OpenGroup(string changeGroupTitle)
{
return this.Context.OpenGroup(changeGroupTitle, new DesignItem[] { this });
}
#region Extensions support
private struct ExtensionEntry
{
internal readonly Extension Extension;
internal readonly ExtensionServer Server;
public ExtensionEntry(Extension extension, ExtensionServer server)
{
this.Extension = extension;
this.Server = server;
}
}
ExtensionServer[] _extensionServers;
bool[] _extensionServerIsApplied;
List<ExtensionEntry> _extensions = new List<ExtensionEntry>();
/// <summary>
/// Gets the extensions registered for this DesignItem.
/// </summary>
public IEnumerable<Extension> Extensions {
get {
return _extensions.Select(x => x.Extension).ToList();
}
}
internal void SetExtensionServers(ExtensionManager extensionManager, ExtensionServer[] extensionServers)
{
Debug.Assert(_extensionServers == null);
Debug.Assert(extensionServers != null);
_extensionServers = extensionServers;
_extensionServerIsApplied = new bool[extensionServers.Length];
for (int i = 0; i < _extensionServers.Length; i++) {
bool shouldApply = _extensionServers[i].ShouldApplyExtensions(this);
if (shouldApply != _extensionServerIsApplied[i]) {
_extensionServerIsApplied[i] = shouldApply;
ApplyUnapplyExtensionServer(extensionManager, shouldApply, _extensionServers[i]);
}
}
}
internal void ReapplyExtensionServer(ExtensionManager extensionManager, ExtensionServer server)
{
Debug.Assert(_extensionServers != null);
for (int i = 0; i < _extensionServers.Length; i++) {
if (_extensionServers[i] == server) {
bool shouldApply = server.ShouldApplyExtensions(this);
if (server.ShouldBeReApplied() && shouldApply && shouldApply == _extensionServerIsApplied[i])
{
_extensionServerIsApplied[i] = false;
ApplyUnapplyExtensionServer(extensionManager, false, server);
}
if (shouldApply != _extensionServerIsApplied[i]) {
_extensionServerIsApplied[i] = shouldApply;
ApplyUnapplyExtensionServer(extensionManager, shouldApply, server);
}
}
}
}
private void ApplyUnapplyExtensionServer(ExtensionManager extensionManager, bool shouldApply, ExtensionServer server)
{
if (shouldApply) {
// add extensions
foreach (Extension ext in extensionManager.CreateExtensions(server, this)) {
_extensions.Add(new ExtensionEntry(ext, server));
}
} else {
// remove extensions
_extensions.RemoveAll(
delegate (ExtensionEntry entry) {
if (entry.Server == server) {
server.RemoveExtension(entry.Extension);
return true;
} else {
return false;
}
});
}
}
/// <summary>
/// Removes one specific Extension
/// </summary>
public void RemoveExtension(Extension extension)
public void RemoveExtension(Extension extension)
{
var hasExtension = this._extensions.Any(x => x.Extension.GetType() == extension.GetType());
if (hasExtension) {
var extensionEntry = this._extensions.FirstOrDefault(x => x.Extension.GetType() == extension.GetType());
//_extensions.Remove(extensionEntry);
extensionEntry.Server.RemoveExtension(extensionEntry.Extension);
}
if (hasExtension) {
var extensionEntry = this._extensions.FirstOrDefault(x => x.Extension.GetType() == extension.GetType());
//_extensions.Remove(extensionEntry);
extensionEntry.Server.RemoveExtension(extensionEntry.Extension);
}
}
/// <summary>
/// Reapplies all extensions.
/// </summary>
public void ReapplyAllExtensions()
{
var manager = this.Services.GetService<Extensions.ExtensionManager>();
List<ExtensionServer> servers =_extensions.GroupBy(entry => entry.Server).Select(grp => grp.First().Server).ToList();
foreach (var server in servers) {
ApplyUnapplyExtensionServer(manager, false, server);
ApplyUnapplyExtensionServer(manager, true, server);
}
}
#endregion
#region Manage behavior
readonly Dictionary<Type, object> _behaviorObjects = new Dictionary<Type, object>();
/// <summary>
/// Adds a bevahior extension object to this design item.
/// </summary>
public void AddBehavior(Type behaviorInterface, object behaviorImplementation)
{
if (behaviorInterface == null)
throw new ArgumentNullException("behaviorInterface");
if (behaviorImplementation == null)
throw new ArgumentNullException("behaviorImplementation");
if (!behaviorInterface.IsInstanceOfType(behaviorImplementation))
throw new ArgumentException("behaviorImplementation must implement bevahiorInterface", "behaviorImplementation");
_behaviorObjects.Add(behaviorInterface, behaviorImplementation);
}
/// <summary>
/// Gets a bevahior extension object from the design item.
/// </summary>
/// <returns>The behavior object, or null if it was not found.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public T GetBehavior<T>() where T : class
{
object obj;
_behaviorObjects.TryGetValue(typeof(T), out obj);
return (T)obj;
}
#endregion
/// <summary>
/// This event is raised whenever a model property on the DesignItem changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the <see cref="PropertyChanged"/> event.
/// </summary>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null) {
PropertyChanged(this, e);
}
}
/// <summary>
/// Gets the name of the content property (the property that contains the logical children)
/// </summary>
public abstract string ContentPropertyName { get; }
/// <summary>
/// Gets the content property (the property that contains the logical children)
/// </summary>
public DesignItemProperty ContentProperty {
get {
if (ContentPropertyName == null) return null;
return Properties[ContentPropertyName];
}
}
/// <summary>
/// Removes this design item from its parent property/collection.
/// </summary>
public void Remove()
{
if (ParentProperty != null) {
if (ParentProperty.IsCollection) {
ParentProperty.CollectionElements.Remove(this);
}
else {
ParentProperty.Reset();
}
}
}
/// <summary>
/// Creates a copy of this design item.
/// </summary>
public abstract DesignItem Clone();
/// <summary>
/// Gets a <see cref="Transform"/> that represents all transforms applied to the item's view.
/// </summary>
public Transform GetCompleteAppliedTransformationToView()
{
var retVal = new TransformGroup();
var v = this.View as Visual;
while (v != null) {
var fe = v as FrameworkElement;
if (fe != null && fe.LayoutTransform != null)
retVal.Children.Add(fe.LayoutTransform);
if (fe != null && fe.RenderTransform != null)
retVal.Children.Add(fe.RenderTransform);
if (v is ContainerVisual && ((ContainerVisual)v).Transform != null) {
retVal.Children.Add(((ContainerVisual)v).Transform);
}
v = v.TryFindParent<Visual>(true);
}
return retVal;
}
/// <summary>
/// Gets the component this DesignSite was created for.
/// </summary>
public int DepthLevel
{
get
{
int j = 0;
var x = this.Parent;
while (x != null)
{
j++;
x = x.Parent;
}
return j;
}
}
}
}
/// <summary>
/// Reapplies all extensions.
/// </summary>
public void ReapplyAllExtensions()
{
var manager = this.Services.GetService<Extensions.ExtensionManager>();
List<ExtensionServer> servers =_extensions.GroupBy(entry => entry.Server).Select(grp => grp.First().Server).ToList();
foreach (var server in servers) {
ApplyUnapplyExtensionServer(manager, false, server);
ApplyUnapplyExtensionServer(manager, true, server);
}
}
#endregion
#region Manage behavior
readonly Dictionary<Type, object> _behaviorObjects = new Dictionary<Type, object>();
/// <summary>
/// Adds a bevahior extension object to this design item.
/// </summary>
public void AddBehavior(Type behaviorInterface, object behaviorImplementation)
{
if (behaviorInterface == null)
throw new ArgumentNullException("behaviorInterface");
if (behaviorImplementation == null)
throw new ArgumentNullException("behaviorImplementation");
if (!behaviorInterface.IsInstanceOfType(behaviorImplementation))
throw new ArgumentException("behaviorImplementation must implement bevahiorInterface", "behaviorImplementation");
_behaviorObjects.Add(behaviorInterface, behaviorImplementation);
}
/// <summary>
/// Gets a bevahior extension object from the design item.
/// </summary>
/// <returns>The behavior object, or null if it was not found.</returns>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
public T GetBehavior<T>() where T : class
{
object obj;
_behaviorObjects.TryGetValue(typeof(T), out obj);
return (T)obj;
}
#endregion
/// <summary>
/// This event is raised whenever a model property on the DesignItem changes.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Raises the <see cref="PropertyChanged"/> event.
/// </summary>
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null) {
PropertyChanged(this, e);
}
}
/// <summary>
/// Gets the name of the content property (the property that contains the logical children)
/// </summary>
public abstract string ContentPropertyName { get; }
/// <summary>
/// Gets the content property (the property that contains the logical children)
/// </summary>
public DesignItemProperty ContentProperty {
get {
if (ContentPropertyName == null) return null;
return Properties[ContentPropertyName];
}
}
/// <summary>
/// Removes this design item from its parent property/collection.
/// </summary>
public void Remove()
{
if (ParentProperty != null) {
if (ParentProperty.IsCollection) {
ParentProperty.CollectionElements.Remove(this);
}
else {
ParentProperty.Reset();
}
}
}
/// <summary>
/// Creates a copy of this design item.
/// </summary>
public abstract DesignItem Clone();
/// <summary>
/// Gets a <see cref="Transform"/> that represents all transforms applied to the item's view.
/// </summary>
public Transform GetCompleteAppliedTransformationToView()
{
var retVal = new TransformGroup();
var v = this.View as Visual;
while (v != null) {
var fe = v as FrameworkElement;
if (fe != null && fe.LayoutTransform != null)
retVal.Children.Add(fe.LayoutTransform);
if (fe != null && fe.RenderTransform != null)
retVal.Children.Add(fe.RenderTransform);
if (v is ContainerVisual && ((ContainerVisual)v).Transform != null) {
retVal.Children.Add(((ContainerVisual)v).Transform);
}
v = v.TryFindParent<Visual>(true);
}
return retVal;
}
/// <summary>
/// Gets the component this DesignSite was created for.
/// </summary>
public int DepthLevel
{
get
{
int j = 0;
var x = this.Parent;
while (x != null)
{
j++;
x = x.Parent;
}
return j;
}
}
}
}