bugfixes when content property is used in property mode
This commit is contained in:
Родитель
d07893f2ad
Коммит
9b17211b1a
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче