Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2237 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
31 changed files with 1204 additions and 78 deletions
@ -0,0 +1,33 @@
@@ -0,0 +1,33 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Controls; |
||||
using System.Windows; |
||||
using System.Windows.Media; |
||||
using System.Windows.Shapes; |
||||
using System.Windows.Controls.Primitives; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
using ICSharpCode.WpfDesign.Designer.Controls; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
||||
{ |
||||
/// <summary>
|
||||
/// A thumb where the look can depend on the IsPrimarySelection property.
|
||||
/// Used by UIElementSelectionRectangle.
|
||||
/// </summary>
|
||||
public class ContainerDragHandle : Control |
||||
{ |
||||
static ContainerDragHandle() |
||||
{ |
||||
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
|
||||
//This style is defined in themes\generic.xaml
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ContainerDragHandle), new FrameworkPropertyMetadata(typeof(ContainerDragHandle))); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,45 @@
@@ -0,0 +1,45 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
||||
{ |
||||
/// <summary>
|
||||
/// A thumb where the look can depend on the IsPrimarySelection property.
|
||||
/// Used by UIElementSelectionRectangle.
|
||||
/// </summary>
|
||||
public class ResizeThumb : Thumb |
||||
{ |
||||
/// <summary>
|
||||
/// Dependency property for <see cref="IsPrimarySelection"/>.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsPrimarySelectionProperty |
||||
= DependencyProperty.Register("IsPrimarySelection", typeof(bool), typeof(ResizeThumb)); |
||||
|
||||
static ResizeThumb() |
||||
{ |
||||
//This OverrideMetadata call tells the system that this element wants to provide a style that is different than its base class.
|
||||
//This style is defined in themes\generic.xaml
|
||||
DefaultStyleKeyProperty.OverrideMetadata(typeof(ResizeThumb), new FrameworkPropertyMetadata(typeof(ResizeThumb))); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets if the resize thumb is attached to the primary selection.
|
||||
/// </summary>
|
||||
public bool IsPrimarySelection { |
||||
get { return (bool)GetValue(IsPrimarySelectionProperty); } |
||||
set { SetValue(IsPrimarySelectionProperty, value); } |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,42 @@
@@ -0,0 +1,42 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows.Controls; |
||||
using System.Windows; |
||||
using System.Windows.Media; |
||||
using System.Windows.Shapes; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
using ICSharpCode.WpfDesign.Designer.Controls; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// The drag handle displayed for panels.
|
||||
/// </summary>
|
||||
[ExtensionServer(typeof(PrimarySelectionExtensionServer))] |
||||
[ExtensionFor(typeof(Panel), OverrideExtension = typeof(TopLeftResizeThumb))] |
||||
public class TopLeftContainerDragHandle : AdornerProvider |
||||
{ |
||||
/// <summary/>
|
||||
public TopLeftContainerDragHandle() |
||||
{ |
||||
ContainerDragHandle rect = new ContainerDragHandle(); |
||||
|
||||
rect.PreviewMouseDown += delegate { |
||||
Services.Selection.SetSelectedComponents(new DesignItem[] { this.ExtendedItem }, SelectionTypes.Auto); |
||||
}; |
||||
|
||||
RelativePlacement p = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top); |
||||
p.XOffset = -1; |
||||
p.YOffset = -1; |
||||
|
||||
AddAdorner(p, AdornerOrder.Background, rect); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,34 @@
@@ -0,0 +1,34 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
using System.Windows.Controls; |
||||
using System.Windows.Controls.Primitives; |
||||
using ICSharpCode.WpfDesign.Adorners; |
||||
using ICSharpCode.WpfDesign.Extensions; |
||||
using ICSharpCode.WpfDesign.Designer.Controls; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// The resize thumb at the top left edge of a component.
|
||||
/// </summary>
|
||||
[ExtensionFor(typeof(FrameworkElement))] |
||||
public class TopLeftResizeThumb : PrimarySelectionAdornerProvider |
||||
{ |
||||
/// <summary></summary>
|
||||
public TopLeftResizeThumb() |
||||
{ |
||||
ResizeThumb resizeThumb = new ResizeThumb(); |
||||
|
||||
RelativePlacement p = new RelativePlacement(HorizontalAlignment.Left, VerticalAlignment.Top); |
||||
AddAdorner(p, AdornerOrder.Foreground, resizeThumb); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,247 @@
@@ -0,0 +1,247 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.Generic; |
||||
using System.Diagnostics; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Services |
||||
{ |
||||
#region ITransactionItem
|
||||
interface ITransactionItem |
||||
{ |
||||
void Do(); |
||||
void Undo(); |
||||
|
||||
string Title { get; set; } |
||||
} |
||||
#endregion
|
||||
|
||||
#region UndoTransaction
|
||||
/// <summary>
|
||||
/// Supports ChangeGroup transactions and undo behavior.
|
||||
/// </summary>
|
||||
sealed class UndoTransaction : ChangeGroup, ITransactionItem |
||||
{ |
||||
public enum TransactionState |
||||
{ |
||||
Open, |
||||
Completed, |
||||
Undone, |
||||
Failed |
||||
} |
||||
|
||||
TransactionState _state; |
||||
|
||||
public TransactionState State |
||||
{ |
||||
get { return _state; } |
||||
} |
||||
|
||||
List<ITransactionItem> items = new List<ITransactionItem>(); |
||||
|
||||
public void Execute(ITransactionItem item) |
||||
{ |
||||
AssertState(TransactionState.Open); |
||||
item.Do(); |
||||
items.Add(item); |
||||
} |
||||
|
||||
private void AssertState(TransactionState expectedState) |
||||
{ |
||||
if (_state != expectedState) |
||||
throw new InvalidOperationException("Expected state " + expectedState + ", but state is " + _state); |
||||
} |
||||
|
||||
public event EventHandler Committed; |
||||
public event EventHandler RolledBack; |
||||
|
||||
public override void Commit() |
||||
{ |
||||
AssertState(TransactionState.Open); |
||||
_state = TransactionState.Completed; |
||||
if (Committed != null) |
||||
Committed(this, EventArgs.Empty); |
||||
} |
||||
|
||||
public override void Abort() |
||||
{ |
||||
AssertState(TransactionState.Open); |
||||
_state = TransactionState.Failed; |
||||
InternalRollback(); |
||||
if (RolledBack != null) |
||||
RolledBack(this, EventArgs.Empty); |
||||
} |
||||
|
||||
public void Undo() |
||||
{ |
||||
AssertState(TransactionState.Completed); |
||||
_state = TransactionState.Undone; |
||||
InternalRollback(); |
||||
} |
||||
|
||||
void InternalRollback() |
||||
{ |
||||
try { |
||||
for (int i = items.Count - 1; i >= 0; i--) { |
||||
items[i].Undo(); |
||||
} |
||||
} catch { |
||||
_state = TransactionState.Failed; |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
public void Redo() |
||||
{ |
||||
AssertState(TransactionState.Undone); |
||||
try { |
||||
for (int i = 0; i < items.Count; i--) { |
||||
items[i].Do(); |
||||
} |
||||
} catch { |
||||
_state = TransactionState.Failed; |
||||
try { |
||||
InternalRollback(); |
||||
} catch (Exception ex) { |
||||
Debug.WriteLine("Exception rolling back after Redo error:\n" + ex.ToString()); |
||||
} |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
void ITransactionItem.Do() |
||||
{ |
||||
if (_state != TransactionState.Completed) { |
||||
Redo(); |
||||
} |
||||
} |
||||
|
||||
protected override void Disposed() |
||||
{ |
||||
if (_state == TransactionState.Open) { |
||||
try { |
||||
Abort(); |
||||
} catch (Exception ex) { |
||||
Debug.WriteLine("Exception rolling back after failure:\n" + ex.ToString()); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
#endregion
|
||||
|
||||
#region UndoService
|
||||
/// <summary>
|
||||
/// Service supporting Undo/Redo actions on the design surface.
|
||||
/// </summary>
|
||||
public sealed class UndoService |
||||
{ |
||||
Stack<UndoTransaction> _transactionStack = new Stack<UndoTransaction>(); |
||||
Stack<ITransactionItem> _undoStack = new Stack<ITransactionItem>(); |
||||
Stack<ITransactionItem> _redoStack = new Stack<ITransactionItem>(); |
||||
|
||||
UndoTransaction CurrentTransaction { |
||||
get { |
||||
if (_transactionStack.Count == 0) |
||||
return null; |
||||
else |
||||
return _transactionStack.Peek(); |
||||
} |
||||
} |
||||
|
||||
internal UndoTransaction StartTransaction() |
||||
{ |
||||
UndoTransaction t = new UndoTransaction(); |
||||
t.Committed += TransactionFinished; |
||||
t.RolledBack += TransactionFinished; |
||||
t.Committed += delegate(object sender, EventArgs e) { |
||||
Execute((UndoTransaction)sender); |
||||
}; |
||||
return t; |
||||
} |
||||
|
||||
void TransactionFinished(object sender, EventArgs e) |
||||
{ |
||||
if (sender != _transactionStack.Pop()) { |
||||
throw new Exception("Invalid transaction finish, nested transactions must finish first"); |
||||
} |
||||
} |
||||
|
||||
internal void Execute(ITransactionItem item) |
||||
{ |
||||
if (_transactionStack.Count == 0) { |
||||
item.Do(); |
||||
_undoStack.Push(item); |
||||
_redoStack.Clear(); |
||||
} else { |
||||
_transactionStack.Peek().Execute(item); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if undo actions are available.
|
||||
/// </summary>
|
||||
public bool CanUndo { |
||||
get { return _undoStack.Count > 0; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Undoes the last action.
|
||||
/// </summary>
|
||||
public void Undo() |
||||
{ |
||||
if (!CanUndo) |
||||
throw new InvalidOperationException("Cannot Undo: undo stack is empty"); |
||||
if (_transactionStack.Count != 0) |
||||
throw new InvalidOperationException("Cannot Undo while transaction is running"); |
||||
ITransactionItem item = _undoStack.Pop(); |
||||
try { |
||||
item.Undo(); |
||||
_redoStack.Push(item); |
||||
} catch { |
||||
// state might be invalid now, clear stacks to prevent getting more inconsistencies
|
||||
Clear(); |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Gets if there are redo actions available.
|
||||
/// </summary>
|
||||
public bool CanRedo { get { return _redoStack.Count > 0; } } |
||||
|
||||
/// <summary>
|
||||
/// Redoes a previously undone action.
|
||||
/// </summary>
|
||||
public void Redo() |
||||
{ |
||||
if (!CanRedo) |
||||
throw new InvalidOperationException("Cannot Redo: redo stack is empty"); |
||||
if (_transactionStack.Count != 0) |
||||
throw new InvalidOperationException("Cannot Redo while transaction is running"); |
||||
ITransactionItem item = _redoStack.Pop(); |
||||
try { |
||||
item.Do(); |
||||
_undoStack.Push(item); |
||||
} catch { |
||||
// state might be invalid now, clear stacks to prevent getting more inconsistencies
|
||||
Clear(); |
||||
throw; |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Clears saved actions (both undo and redo stack).
|
||||
/// </summary>
|
||||
public void Clear() |
||||
{ |
||||
_undoStack.Clear(); |
||||
_redoStack.Clear(); |
||||
} |
||||
} |
||||
#endregion
|
||||
} |
@ -0,0 +1,85 @@
@@ -0,0 +1,85 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using ICSharpCode.WpfDesign.XamlDom; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Xaml |
||||
{ |
||||
sealed class XamlModelProperty : DesignItemProperty |
||||
{ |
||||
readonly XamlDesignItem _designItem; |
||||
readonly XamlProperty _property; |
||||
|
||||
public XamlModelProperty(XamlDesignItem designItem, XamlProperty property) |
||||
{ |
||||
this._designItem = designItem; |
||||
this._property = property; |
||||
} |
||||
|
||||
public override bool IsCollection { |
||||
get { |
||||
return _property.IsCollection; |
||||
} |
||||
} |
||||
|
||||
public override System.Collections.Generic.IList<DesignItem> CollectionElements { |
||||
get { |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
|
||||
public override DesignItem Value { |
||||
get { |
||||
if (IsCollection) |
||||
throw new DesignerException("Cannot access Value for collection properties."); |
||||
|
||||
XamlComponentService componentService = _designItem.ComponentService; |
||||
object valueOnInstance = this.ValueOnInstance; |
||||
DesignItem designItem = componentService.GetDesignItem(valueOnInstance); |
||||
if (designItem != null) |
||||
return designItem; |
||||
|
||||
return componentService.RegisterComponentForDesigner(valueOnInstance); |
||||
} |
||||
} |
||||
|
||||
public override object ValueOnInstance { |
||||
get { |
||||
return _property.ValueOnInstance; |
||||
} |
||||
set { |
||||
_property.ValueOnInstance = value; |
||||
} |
||||
} |
||||
|
||||
public override bool IsSet { |
||||
get { |
||||
return _property.IsSet; |
||||
} |
||||
} |
||||
|
||||
public override void SetValue(object value) |
||||
{ |
||||
XamlComponentService componentService = _designItem.ComponentService; |
||||
|
||||
DesignItem designItem = componentService.GetDesignItem(value); |
||||
if (designItem != null) { |
||||
if (designItem.Parent != null) |
||||
throw new DesignerException("Cannot set value to design item that already has a parent"); |
||||
} else { |
||||
designItem = componentService.RegisterComponentForDesigner(value); |
||||
} |
||||
|
||||
} |
||||
|
||||
public override void Reset() |
||||
{ |
||||
_property.Reset(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,41 @@
@@ -0,0 +1,41 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Windows; |
||||
using ICSharpCode.WpfDesign.XamlDom; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Xaml |
||||
{ |
||||
sealed class XamlModelPropertyCollection : DesignItemPropertyCollection |
||||
{ |
||||
XamlDesignItem _item; |
||||
|
||||
public XamlModelPropertyCollection(XamlDesignItem item) |
||||
{ |
||||
this._item = item; |
||||
} |
||||
|
||||
public override DesignItemProperty this[DependencyProperty dependencyProperty] { |
||||
get { |
||||
//return new XamlModelProperty(_item, dependencyProperty);
|
||||
return this[dependencyProperty.Name]; |
||||
} |
||||
} |
||||
|
||||
public override DesignItemProperty this[string name] { |
||||
get { |
||||
return new XamlModelProperty(_item, _item.XamlObject.FindOrCreateProperty(name)); |
||||
} |
||||
} |
||||
|
||||
public override System.Collections.Generic.IEnumerator<DesignItemProperty> GetEnumerator() |
||||
{ |
||||
throw new NotImplementedException(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" |
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
||||
xmlns:src="clr-namespace:ICSharpCode.WpfDesign.Designer" |
||||
> |
||||
|
||||
<Style TargetType="{x:Type src:Controls.ResizeThumb}"> |
||||
<Setter Property="Template"> |
||||
<Setter.Value> |
||||
<ControlTemplate TargetType="{x:Type src:Controls.ResizeThumb}"> |
||||
<Rectangle Name="thumbRectangle" |
||||
Width="7" Height="7" SnapsToDevicePixels="True" |
||||
Stroke="Black" Fill="White" RadiusX="1.4142" RadiusY="1.4142"/> |
||||
<ControlTemplate.Triggers> |
||||
<Trigger Property="IsPrimarySelection" Value="False"> |
||||
<Setter TargetName="thumbRectangle" Property="Stroke" Value="White"/> |
||||
<Setter TargetName="thumbRectangle" Property="Fill" Value="Black"/> |
||||
</Trigger> |
||||
<Trigger Property="IsEnabled" Value="False"> |
||||
<Setter TargetName="thumbRectangle" Property="Fill" Value="Gray"/> |
||||
</Trigger> |
||||
</ControlTemplate.Triggers> |
||||
</ControlTemplate> |
||||
</Setter.Value> |
||||
</Setter> |
||||
</Style> |
||||
|
||||
<Style TargetType="{x:Type src:Controls.ContainerDragHandle}"> |
||||
<Setter Property="Template"> |
||||
<Setter.Value> |
||||
<ControlTemplate TargetType="{x:Type src:Controls.ContainerDragHandle}"> |
||||
<Canvas Height="13" Width="13" Name="Canvas" Background="#00FFFFFF" SnapsToDevicePixels="True"> |
||||
<Rectangle Height="13" Width="13" RadiusX="2" RadiusY="2" |
||||
Fill="#669ABFE5" Name="BorderRectangle" Stroke="#FF9ABFE5" StrokeThickness="1" /> |
||||
<Path Fill="#FF748EAA" Canvas.Left="1" Canvas.Top="1"> |
||||
<Path.Data> |
||||
<GeometryGroup> |
||||
<PathGeometry Figures="M5.5,0L3,3L8,3 M11,5.5L8,3L8,8 M5.5,11L3,8L8,8 M0,5.5L3,3L3,8" /> |
||||
<RectangleGeometry Rect="3,5,5,1" /> |
||||
<RectangleGeometry Rect="5,3,1,5" /> |
||||
<RectangleGeometry Rect="5,5,1,1" /> |
||||
</GeometryGroup> |
||||
</Path.Data> |
||||
</Path> |
||||
</Canvas> |
||||
</ControlTemplate> |
||||
</Setter.Value> |
||||
</Setter> |
||||
</Style> |
||||
</ResourceDictionary> |
@ -0,0 +1,47 @@
@@ -0,0 +1,47 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.WpfDesign |
||||
{ |
||||
/// <summary>
|
||||
/// Base class for change groups.
|
||||
/// </summary>
|
||||
public abstract class ChangeGroup : IDisposable |
||||
{ |
||||
string title; |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the title of the change group.
|
||||
/// </summary>
|
||||
public string Title { |
||||
get { return title; } |
||||
set { title = value; } |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Commits the change group.
|
||||
/// </summary>
|
||||
public abstract void Commit(); |
||||
|
||||
/// <summary>
|
||||
/// Aborts the change group.
|
||||
/// </summary>
|
||||
public abstract void Abort(); |
||||
|
||||
/// <summary>
|
||||
/// Is called when the change group is disposed. Should Abort the change group if it is not already committed.
|
||||
/// </summary>
|
||||
protected abstract void Disposed(); |
||||
|
||||
void IDisposable.Dispose() |
||||
{ |
||||
Disposed(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,86 @@
@@ -0,0 +1,86 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
using System.Collections.ObjectModel; |
||||
using System.Collections.Generic; |
||||
using System.Windows; |
||||
|
||||
namespace ICSharpCode.WpfDesign |
||||
{ |
||||
/// <summary>
|
||||
/// Represents a property of a DesignItem.
|
||||
/// All changes done via the DesignItemProperty class are represented in the underlying model (e.g. XAML).
|
||||
/// This also ensures that
|
||||
/// Changes directly done to control instances might not be reflected in the model.
|
||||
/// </summary>
|
||||
public abstract class DesignItemProperty |
||||
{ |
||||
/// <summary>
|
||||
/// Gets if the property represents a collection.
|
||||
/// </summary>
|
||||
public abstract bool IsCollection { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the elements represented by the collection.
|
||||
/// </summary>
|
||||
public abstract IList<DesignItem> CollectionElements { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the value of the property. This property returns null if the value is not set.
|
||||
/// </summary>
|
||||
public abstract DesignItem Value { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets/Sets the value of the property on the designed instance.
|
||||
/// If the property is not set, this returns the default value.
|
||||
/// The setter does NOT update the underlying model, use SetValue() instead!
|
||||
/// </summary>
|
||||
public abstract object ValueOnInstance { get; set; } |
||||
|
||||
/// <summary>
|
||||
/// Sets the value of the property.
|
||||
/// </summary>
|
||||
public abstract void SetValue(object value); |
||||
|
||||
/// <summary>
|
||||
/// Gets if the property is set on the design item.
|
||||
/// </summary>
|
||||
public abstract bool IsSet { get; } |
||||
|
||||
/// <summary>
|
||||
/// Resets the property value to the default, possibly removing it from the list of properties.
|
||||
/// </summary>
|
||||
public abstract void Reset(); |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Represents a collection of design item properties.
|
||||
/// </summary>
|
||||
public abstract class DesignItemPropertyCollection : IEnumerable<DesignItemProperty> |
||||
{ |
||||
/// <summary>
|
||||
/// Gets the design item property representing the specified dependency property.
|
||||
/// </summary>
|
||||
public abstract DesignItemProperty this[DependencyProperty dependencyProperty] { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets the property with the specified name.
|
||||
/// </summary>
|
||||
public abstract DesignItemProperty this[string name] { get; } |
||||
|
||||
/// <summary>
|
||||
/// Gets an enumerator to enumerate the properties that have a non-default value.
|
||||
/// </summary>
|
||||
public abstract IEnumerator<DesignItemProperty> GetEnumerator(); |
||||
|
||||
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() |
||||
{ |
||||
return this.GetEnumerator(); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Extensions |
||||
{ |
||||
/// <summary>
|
||||
/// Combines two extension servers using a logical OR.
|
||||
/// </summary>
|
||||
public sealed class LogicalOrExtensionServer<A, B> : DefaultExtensionServer |
||||
where A : ExtensionServer |
||||
where B : ExtensionServer |
||||
{ |
||||
ExtensionServer _a; |
||||
ExtensionServer _b; |
||||
|
||||
/// <summary/>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
_a = Context.Services.ExtensionManager.GetExtensionServer(new ExtensionServerAttribute(typeof(A))); |
||||
_b = Context.Services.ExtensionManager.GetExtensionServer(new ExtensionServerAttribute(typeof(B))); |
||||
_a.ShouldApplyExtensionsInvalidated += OnShouldApplyExtensionsInvalidated; |
||||
_b.ShouldApplyExtensionsInvalidated += OnShouldApplyExtensionsInvalidated; |
||||
} |
||||
|
||||
void OnShouldApplyExtensionsInvalidated(object sender, DesignItemCollectionEventArgs e) |
||||
{ |
||||
ReapplyExtensions(e.Items); |
||||
} |
||||
|
||||
/// <summary/>
|
||||
public override bool ShouldApplyExtensions(DesignItem extendedItem) |
||||
{ |
||||
return _a.ShouldApplyExtensions(extendedItem) || _b.ShouldApplyExtensions(extendedItem); |
||||
} |
||||
} |
||||
|
||||
/// <summary>
|
||||
/// Combines two extension servers using a logical AND.
|
||||
/// </summary>
|
||||
public sealed class LogicalAndExtensionServer<A, B> : DefaultExtensionServer |
||||
where A : ExtensionServer |
||||
where B : ExtensionServer |
||||
{ |
||||
ExtensionServer _a; |
||||
ExtensionServer _b; |
||||
|
||||
/// <summary/>
|
||||
protected override void OnInitialized() |
||||
{ |
||||
base.OnInitialized(); |
||||
_a = Context.Services.ExtensionManager.GetExtensionServer(new ExtensionServerAttribute(typeof(A))); |
||||
_b = Context.Services.ExtensionManager.GetExtensionServer(new ExtensionServerAttribute(typeof(B))); |
||||
_a.ShouldApplyExtensionsInvalidated += OnShouldApplyExtensionsInvalidated; |
||||
_b.ShouldApplyExtensionsInvalidated += OnShouldApplyExtensionsInvalidated; |
||||
} |
||||
|
||||
void OnShouldApplyExtensionsInvalidated(object sender, DesignItemCollectionEventArgs e) |
||||
{ |
||||
ReapplyExtensions(e.Items); |
||||
} |
||||
|
||||
/// <summary/>
|
||||
public override bool ShouldApplyExtensions(DesignItem extendedItem) |
||||
{ |
||||
return _a.ShouldApplyExtensions(extendedItem) && _b.ShouldApplyExtensions(extendedItem); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue