Browse Source

Remove old code. Automatic brace layout for WpfDesign files.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@3285 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Ivan Shumilin 17 years ago
parent
commit
e0c53f5890
  1. 110
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ChooseClass.cs
  2. 69
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ChooseClassDialog.xaml
  3. 114
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ChooseClassDialog.xaml.cs
  4. 20
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ChooseClassService.cs
  5. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GridAdorner.cs
  6. 5
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ClickOrDragMouseGesture.cs
  7. 11
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/UndoService.cs
  8. 8
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlParser.cs
  9. 14
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/HashSet.cs
  10. 30
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/BooleanEditor.cs
  11. 49
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataEvent.cs
  12. 61
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataMember.cs
  13. 96
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataProperty.cs
  14. 206
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataSource.cs
  15. 120
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/EditorManager.cs
  16. 69
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/FallbackEditor.cs
  17. 178
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/IPropertyEditorDataSource.cs
  18. 230
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultipleSelectionDataProperty.cs
  19. 144
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultipleSelectionDataSource.cs
  20. 50
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/PropertyEditorAttribute.cs
  21. 137
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/PropertyEditorBindingHelper.cs
  22. 109
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/ProxyPropertyEditorDataProperty.cs
  23. 34
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/StandardValuesComboBoxEditor.cs
  24. 163
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/TextBoxEditor.cs
  25. 39
      src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/TypeEditorAttribute.cs

110
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ChooseClass.cs

@ -1,110 +0,0 @@ @@ -1,110 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Data;
using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.WpfDesign.AddIn
{
public class ChooseClass : INotifyPropertyChanged
{
public ChooseClass(IProjectContent projectContent)
{
this.projectContent = projectContent;
AddClassesRecursive("");
projectClasses.Sort((c1, c2) => c1.Name.CompareTo(c2.Name));
classes = new ListCollectionView(projectClasses);
classes.Filter = FilterPredicate;
}
IProjectContent projectContent;
List<IClass> projectClasses = new List<IClass>();
void AddClassesRecursive(string ns)
{
foreach (var item in projectContent.GetNamespaceContents(ns)) {
if (item is string) {
AddClassesRecursive(ns.Length == 0 ? item.ToString() : ns + "." + item);
} else if (item is IClass) {
IClass c = item as IClass;
if (c.IsPartial) {
if (projectClasses.Contains(c)) continue;
}
if (c.ClassType == ClassType.Class && c.IsPublic) {
projectClasses.Add(c);
}
}
}
}
ListCollectionView classes;
public ICollectionView Classes {
get { return classes; }
}
string filter;
public string Filter {
get {
return filter;
}
set {
filter = value;
Classes.Refresh();
RaisePropertyChanged("Filter");
}
}
bool showSystemClasses;
public bool ShowSystemClasses {
get {
return showSystemClasses;
}
set {
showSystemClasses = value;
Classes.Refresh();
RaisePropertyChanged("ShowSystemClasses");
}
}
public IClass CurrentClass {
get { return Classes.CurrentItem as IClass; }
}
bool FilterPredicate(object item)
{
IClass c = item as IClass;
if (!ShowSystemClasses) {
if (c.Namespace.StartsWith("System") || c.Namespace.StartsWith("Microsoft")) {
return false;
}
}
return Match(c.Name, Filter);
}
static bool Match(string className, string filter)
{
if (string.IsNullOrEmpty(filter))
return true;
else
return className.StartsWith(filter, StringComparison.InvariantCultureIgnoreCase);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string name)
{
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
}

69
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ChooseClassDialog.xaml

@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
<Window x:Class="ICSharpCode.WpfDesign.AddIn.ChooseClassDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sd="clr-namespace:ICSharpCode.WpfDesign.AddIn"
Background="{x:Static SystemColors.ControlBrush}"
SnapsToDevicePixels="True"
WindowStartupLocation="CenterScreen"
ResizeMode="CanResizeWithGrip"
Title="Choose Class"
Height="438"
Width="488">
<Grid>
<TextBlock Text="Starts with:"
HorizontalAlignment="Left"
Margin="12,12,0,0"
VerticalAlignment="Top"
Height="13"
Width="55" />
<TextBox x:Name="uxFilter"
Text="{Binding Filter, UpdateSourceTrigger=PropertyChanged}"
Height="23"
Margin="12,31,12,0"
VerticalAlignment="Top" />
<sd:ClassListBox x:Name="uxList"
Margin="12,60,12,78"
ItemsSource="{Binding Classes}"
IsSynchronizedWithCurrentItem="True"
ScrollViewer.HorizontalScrollBarVisibility="Hidden"
>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{sd:GetBitmap Icons.16x16.Class}"
Stretch="None" />
<TextBlock Margin="5 0 0 0"
Text="{Binding Converter={x:Static sd:ClassNameConverter.Instance}}"
VerticalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</sd:ClassListBox>
<CheckBox Content="Show System Classes"
IsChecked="{Binding ShowSystemClasses}"
Height="16"
HorizontalAlignment="Left"
Margin="12,0,0,56"
VerticalAlignment="Bottom"
Width="120" />
<Button x:Name="uxOk"
Content="OK"
Height="23"
Margin="0,0,93,12"
VerticalAlignment="Bottom"
HorizontalAlignment="Right"
Width="75"
IsDefault="True"
IsEnabled="{Binding SelectedItem, ElementName=uxList, Converter={x:Static sd:NullToBoolConverter.Instance}}"/>
<Button Content="Cancel"
Height="23"
HorizontalAlignment="Right"
Margin="0,0,12,12"
VerticalAlignment="Bottom"
Width="75"
IsCancel="True" />
</Grid>
</Window>

114
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ChooseClassDialog.xaml.cs

@ -1,114 +0,0 @@ @@ -1,114 +0,0 @@
using System;
using System.Collections.Specialized;
using System.Globalization;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.WpfDesign.AddIn
{
public partial class ChooseClassDialog
{
public ChooseClassDialog(ChooseClass core)
{
DataContext = core;
InitializeComponent();
uxFilter.Focus();
uxList.MouseDoubleClick += uxList_MouseDoubleClick;
uxOk.Click += delegate { Ok(); };
AddHandler(Keyboard.GotKeyboardFocusEvent,
new KeyboardFocusChangedEventHandler(
(sender, e) => uxList.SetValue(IsSelectionActivePropertyKey, true)
),
true);
}
//HACK: listbox is always highlighted
public static DependencyPropertyKey IsSelectionActivePropertyKey =
(DependencyPropertyKey)typeof(Selector).GetField("IsSelectionActivePropertyKey",
BindingFlags.Static | BindingFlags.NonPublic).GetValue(null);
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Enter) {
Ok();
e.Handled = true;
} else if (e.Key == Key.Up) {
uxList.SelectedIndex = Math.Max(0, uxList.SelectedIndex - 1);
e.Handled = true;
} else if (e.Key == Key.Down) {
uxList.SelectedIndex++;
e.Handled = true;
}
}
void uxList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
var f = e.OriginalSource as FrameworkElement;
if (f != null && f.DataContext is IClass) {
Ok();
}
}
void Ok()
{
DialogResult = true;
Close();
}
}
class ClassListBox : ListBox
{
protected override void OnItemsChanged(NotifyCollectionChangedEventArgs e)
{
base.OnItemsChanged(e);
SelectedIndex = 0;
ScrollIntoView(SelectedItem);
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
ScrollIntoView(SelectedItem);
}
}
public class ClassNameConverter : IValueConverter
{
public static ClassNameConverter Instance = new ClassNameConverter();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var c = value as IClass;
if (c == null) return value;
return c.Name + " (" + c.Namespace + ")";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public class NullToBoolConverter : IValueConverter
{
public static NullToBoolConverter Instance = new NullToBoolConverter();
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return value == null ? false : true;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}

20
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.AddIn/Src/ChooseClassService.cs

@ -1,20 +0,0 @@ @@ -1,20 +0,0 @@
using System;
using ICSharpCode.SharpDevelop;
using ICSharpCode.SharpDevelop.Dom;
namespace ICSharpCode.WpfDesign.AddIn
{
public class ChooseClassService
{
public IClass ChooseClass()
{
var core = new ChooseClass(ParserService.CurrentProjectContent);
var window = new ChooseClassDialog(core);
if (window.ShowDialog().Value) {
return core.CurrentClass;
}
return null;
}
}
}

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/GridAdorner.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
@ -227,8 +227,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls @@ -227,8 +227,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls
double mousePos = GetCoordinate(e.GetPosition(grid));
if (activeChangeGroup == null) {
if (Math.Abs(mousePos - mouseStartPos)
>= GetCoordinate(new Point(SystemParameters.MinimumHorizontalDragDistance, SystemParameters.MinimumVerticalDragDistance)))
{
>= GetCoordinate(new Point(SystemParameters.MinimumHorizontalDragDistance, SystemParameters.MinimumVerticalDragDistance))) {
activeChangeGroup = gridItem.OpenGroup("Change grid row/column size");
RememberOriginalSize();
}

5
src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Services/ClickOrDragMouseGesture.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
@ -35,8 +35,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -35,8 +35,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services
if (!hasDragStarted) {
Vector v = e.GetPosition(positionRelativeTo) - startPoint;
if (Math.Abs(v.X) >= SystemParameters.MinimumHorizontalDragDistance
|| Math.Abs(v.Y) >= SystemParameters.MinimumVerticalDragDistance)
{
|| Math.Abs(v.Y) >= SystemParameters.MinimumVerticalDragDistance) {
hasDragStarted = true;
OnDragStarted(e);
}

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

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
@ -66,8 +66,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -66,8 +66,7 @@ namespace ICSharpCode.WpfDesign.Designer.Services
TransactionState _state;
public TransactionState State
{
public TransactionState State {
get { return _state; }
}
@ -79,10 +78,8 @@ namespace ICSharpCode.WpfDesign.Designer.Services @@ -79,10 +78,8 @@ namespace ICSharpCode.WpfDesign.Designer.Services
item.Do();
var a = item as XamlModelProperty.PropertyChangeAction;
if (a != null)
{
foreach (var b in items.OfType<XamlModelProperty.PropertyChangeAction>())
{
if (a != null) {
foreach (var b in items.OfType<XamlModelProperty.PropertyChangeAction>()) {
if (b.MergeWith(a)) return;
}
}

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

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
@ -265,8 +265,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -265,8 +265,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
}
}
if (defaultProperty != null && !defaultProperty.IsCollection && !element.IsEmpty)
{
if (defaultProperty != null && !defaultProperty.IsCollection && !element.IsEmpty) {
// Runs even when defaultValueSet==false!
// Again, no idea why the official XamlReader does this.
defaultProperty.GetValue(obj.Instance);
@ -298,8 +297,7 @@ namespace ICSharpCode.WpfDesign.XamlDom @@ -298,8 +297,7 @@ namespace ICSharpCode.WpfDesign.XamlDom
while (node != null
&& (node.NodeType == XmlNodeType.Text
|| node.NodeType == XmlNodeType.CDATA
|| node.NodeType == XmlNodeType.SignificantWhitespace))
{
|| node.NodeType == XmlNodeType.SignificantWhitespace)) {
combinedNormalizedChildNodes++;
if (text != null) text.Value += node.Value;

14
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/HashSet.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
@ -110,8 +110,7 @@ namespace ICSharpCode.WpfDesign @@ -110,8 +110,7 @@ namespace ICSharpCode.WpfDesign
/// <summary>
/// Gets the number of items in the collection.
/// </summary>
public int Count
{
public int Count {
get { return _dict.Count; }
}
@ -147,8 +146,7 @@ namespace ICSharpCode.WpfDesign @@ -147,8 +146,7 @@ namespace ICSharpCode.WpfDesign
this.Add(item);
}
bool ICollection<T>.IsReadOnly
{
bool ICollection<T>.IsReadOnly {
get { return false; }
}
@ -174,13 +172,11 @@ namespace ICSharpCode.WpfDesign @@ -174,13 +172,11 @@ namespace ICSharpCode.WpfDesign
((ICollection)_dict).CopyTo(array, index);
}
bool ICollection.IsSynchronized
{
bool ICollection.IsSynchronized {
get { return false; }
}
object ICollection.SyncRoot
{
object ICollection.SyncRoot {
get { return null; }
}

30
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/BooleanEditor.cs

@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
// <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.Diagnostics;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Documents;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// Type editor used to edit bool properties.
/// </summary>
sealed class BooleanEditor : CheckBox
{
/// <summary>
/// Creates a new BooleanEditor instance.
/// </summary>
public BooleanEditor(IPropertyEditorDataProperty property)
{
SetBinding(IsCheckedProperty, PropertyEditorBindingHelper.CreateBinding(this, property));
}
}
}

49
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataEvent.cs

@ -1,49 +0,0 @@ @@ -1,49 +0,0 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 2667$</version>
// </file>
using System;
using System.Diagnostics;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// wraps a DesignItemDataProperty (with IsEvent=true) for the property editor/grid.
/// </summary>
sealed class DesignItemDataEvent : DesignItemDataMember, IPropertyEditorDataEvent
{
internal DesignItemDataEvent(DesignItemDataSource ownerDataSource, DesignItemProperty property)
: base(ownerDataSource, property)
{
Debug.Assert(property.IsEvent);
}
public event EventHandler HandlerNameChanged {
add { property.ValueChanged += value; }
remove { property.ValueChanged -= value; }
}
public string HandlerName {
get {
return (string)property.ValueOnInstance;
}
set {
if (string.IsNullOrEmpty(value))
property.Reset();
else
property.SetValue(value);
}
}
public void GoToHandler()
{
IEventHandlerService ehs = ownerDataSource.Services.GetService<IEventHandlerService>();
if (ehs != null) {
ehs.CreateEventHandler(ownerDataSource.DesignItem, property);
}
}
}
}

61
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataMember.cs

@ -1,61 +0,0 @@ @@ -1,61 +0,0 @@
// <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.Diagnostics;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// wraps a DesignItemDataProperty for the property editor/grid.
/// </summary>
class DesignItemDataMember : IPropertyEditorDataMember
{
protected readonly DesignItemDataSource ownerDataSource;
protected readonly DesignItemProperty property;
protected DesignItemDataMember(DesignItemDataSource ownerDataSource, DesignItemProperty property)
{
Debug.Assert(ownerDataSource != null);
Debug.Assert(property != null);
this.ownerDataSource = ownerDataSource;
this.property = property;
}
public IPropertyEditorDataSource OwnerDataSource {
get { return ownerDataSource; }
}
public string Name {
get { return property.Name; }
}
public object GetDescription()
{
IPropertyDescriptionService p = ownerDataSource.DesignItem.Services.GetService<IPropertyDescriptionService>();
if (p != null)
return p.GetDescription(property);
else
return null;
}
/// <summary>
/// Gets the type that declares the property.
/// </summary>
public Type DeclaringType {
get { return property.DeclaringType; }
}
/// <summary>
/// Gets the type of the property value.
/// </summary>
public Type ReturnType {
get { return property.ReturnType; }
}
}
}

96
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataProperty.cs

@ -1,96 +0,0 @@ @@ -1,96 +0,0 @@
// <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.Diagnostics;
using System.Windows;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// wraps a DesignItemDataProperty (with IsEvent=false) for the property editor/grid.
/// </summary>
sealed class DesignItemDataProperty : DesignItemDataMember, IPropertyEditorDataProperty
{
internal DesignItemDataProperty(DesignItemDataSource ownerDataSource, DesignItemProperty property)
: base(ownerDataSource, property)
{
Debug.Assert(!property.IsEvent);
}
public string Category {
get { return property.Category; }
}
public System.ComponentModel.TypeConverter TypeConverter {
get { return property.TypeConverter; }
}
public bool IsSet {
get {
return property.IsSet;
}
set {
if (value != property.IsSet) {
if (value) {
// copy default value to local value
property.SetValue(property.ValueOnInstance);
} else {
property.Reset();
}
}
}
}
public event EventHandler IsSetChanged {
add { property.IsSetChanged += value; }
remove { property.IsSetChanged -= value; }
}
public bool IsAmbiguous {
get { return false; }
}
public object Value {
get {
return property.ValueOnInstance;
}
set {
property.SetValue(value);
}
}
public event EventHandler ValueChanged {
add { property.ValueChanged += value; }
remove { property.ValueChanged -= value; }
}
public bool CanUseCustomExpression {
get {
return true;
}
}
public void SetCustomExpression(string expression)
{
throw new NotImplementedException();
}
/// <summary>
/// Creates a UIElement that can edit the property value.
/// </summary>
public UIElement CreateEditor()
{
EditorManager manager = ownerDataSource.Services.GetService<EditorManager>();
if (manager != null) {
return manager.CreateEditor(this);
} else {
return new FallbackEditor(this);
}
}
}
}

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

@ -1,206 +0,0 @@ @@ -1,206 +0,0 @@
// <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.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// Implements IPropertyEditorDataSource accessing the properties on a DesignItem.
/// </summary>
public sealed class DesignItemDataSource : IPropertyEditorDataSource
{
readonly DesignItem item;
readonly List<IPropertyEditorDataProperty> properties = new List<IPropertyEditorDataProperty>();
readonly List<IPropertyEditorDataEvent> events = new List<IPropertyEditorDataEvent>();
#region Available properties
// cache properties available for a type - retrieving this list takes ~100ms on my machine, so
// we cannot do this for every selected component, but must reuse the list
static readonly Dictionary<Type, string[]> availableProperties = new Dictionary<Type, string[]>();
static string[] GetAvailableProperties(Type forType)
{
Debug.Assert(forType != null);
string[] result;
lock (availableProperties) {
if (availableProperties.TryGetValue(forType, out result))
return result;
}
List<string> names = new List<string>();
foreach (PropertyDescriptor p in TypeDescriptor.GetProperties(forType)) {
if (!p.IsBrowsable) continue;
if (p.IsReadOnly) continue;
if (p.Name.Contains(".")) continue;
names.Add(p.Name);
}
result = names.ToArray();
lock (availableProperties) {
availableProperties[forType] = result;
}
return result;
}
#endregion
#region Available events
// cache events available for a type
static readonly Dictionary<Type, string[]> availableEvents = new Dictionary<Type, string[]>();
static string[] GetAvailableEvents(Type forType)
{
Debug.Assert(forType != null);
string[] result;
lock (availableEvents) {
if (availableEvents.TryGetValue(forType, out result))
return result;
}
List<string> names = new List<string>();
foreach (EventDescriptor p in TypeDescriptor.GetEvents(forType)) {
if (!p.IsBrowsable) continue;
if (p.Name.Contains(".")) continue;
names.Add(p.Name);
}
result = names.ToArray();
lock (availableEvents) {
availableEvents[forType] = result;
}
return result;
}
#endregion
/// <summary>
/// Constructs a new DesignItemDataSource for the specified design item.
/// </summary>
public DesignItemDataSource(DesignItem item)
{
if (item == null)
throw new ArgumentNullException("item");
this.item = item;
List<DesignItemProperty> designItemProperties = new List<DesignItemProperty>();
foreach (string name in GetAvailableProperties(item.ComponentType)) {
designItemProperties.Add(item.Properties[name]);
}
foreach (string name in GetAvailableEvents(item.ComponentType)) {
designItemProperties.Add(item.Properties[name]);
}
designItemProperties.AddRange(item.Properties);
foreach (DesignItemProperty p in designItemProperties.Distinct()) {
if (p.IsEvent) {
events.Add(new DesignItemDataEvent(this, p));
} else {
properties.Add(new DesignItemDataProperty(this, p));
}
}
}
/// <summary>
/// Gets a data source for the specified design item.
/// This tries to get an existing data source instance (as behavior), or constructs a new
/// DesignItemDataSource instance if that fails.
/// </summary>
public static IPropertyEditorDataSource GetDataSourceForDesignItem(DesignItem item)
{
return item.GetBehavior<IPropertyEditorDataSource>() ?? new DesignItemDataSource(item);
}
/// <summary>
/// Gets a data source for the specified design item.
/// This tries to get an existing data source instance (as behavior), or constructs a new
/// DesignItemDataSource instance if that fails.
/// </summary>
public static IPropertyEditorDataSource GetDataSourceForDesignItems(ICollection<DesignItem> items)
{
IPropertyEditorDataSource[] sources = new IPropertyEditorDataSource[items.Count];
DesignContext context = null;
int i = 0;
foreach (DesignItem item in items) {
if (context == null)
context = item.Context;
else if (context != item.Context)
throw new DesignerException("All specified items must use the same design context!");
sources[i++] = GetDataSourceForDesignItem(item);
}
return MultipleSelectionDataSource.CreateDataSource(context != null ? context.Services : null, sources);
}
/// <summary>
/// Gets the design item for which this DesignItemDataSource was created.
/// </summary>
public DesignItem DesignItem {
get { return item; }
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public string Name {
get { return item.Name ?? ""; }
set { item.Name = value; }
}
/// <summary>
/// Is raised when the name of the design item changes.
/// </summary>
public event EventHandler NameChanged {
add { item.NameChanged += value; }
remove { item.NameChanged -= value; }
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public string Type {
get {
return item.ComponentType.Name;
}
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public ImageSource Icon {
get { return null; }
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public ICollection<IPropertyEditorDataProperty> Properties {
get { return properties.AsReadOnly(); }
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public ICollection<IPropertyEditorDataEvent> Events {
get { return events.AsReadOnly(); }
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public bool CanAddAttachedProperties {
get {
return item.Component is DependencyObject;
}
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public ServiceContainer Services {
get { return item.Services; }
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public Brush CreateThumbnailBrush()
{
if (item.View != null) {
VisualBrush b = new VisualBrush(item.View);
b.AutoLayoutContent = false;
return b;
} else {
return null;
}
}
}
}

120
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/EditorManager.cs

@ -1,120 +0,0 @@ @@ -1,120 +0,0 @@
// <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.ComponentModel;
using System.Diagnostics;
using System.Collections.Generic;
using System.Reflection;
using System.Windows;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// Manages registered type and property editors.
/// </summary>
public sealed class EditorManager
{
// property return type => editor type
Dictionary<Type, Type> _typeEditors = new Dictionary<Type, Type>();
// property full name => editor type
Dictionary<string, Type> _propertyEditors = new Dictionary<string, Type>();
/// <summary>
/// Creates an editor for the specified property.
/// </summary>
public UIElement CreateEditor(IPropertyEditorDataProperty property)
{
try {
return (UIElement)Activator.CreateInstance(GetEditorType(property), property);
} catch (Exception ex) {
Debug.WriteLine(ex.ToString());
throw;
}
}
/// <summary>
/// Creates the fallback editor for the specified property.
/// </summary>
public static UIElement CreateFallbackEditor(IPropertyEditorDataProperty property)
{
return (UIElement)Activator.CreateInstance(GetFallbackEditorType(property), property);
}
/// <summary>
/// Gets the type of the editor that can edit the specified property.
/// </summary>
public Type GetEditorType(IPropertyEditorDataProperty property)
{
if (property == null)
throw new ArgumentNullException("property");
Type editorType;
if (_propertyEditors.TryGetValue(property.DeclaringType.FullName + "." + property.Name, out editorType))
return editorType;
else if (_typeEditors.TryGetValue(property.ReturnType, out editorType))
return editorType;
else
return GetFallbackEditorType(property);
}
/// <summary>
/// Gets the type of the fallback editor used for the specified property.
/// </summary>
public static Type GetFallbackEditorType(IPropertyEditorDataProperty property)
{
if (property == null)
throw new ArgumentNullException("property");
Type returnType = property.ReturnType;
if (returnType.IsEnum) {
return typeof(StandardValuesComboBoxEditor);
} else if (returnType == typeof(bool)) {
return typeof(BooleanEditor);
} else {
TypeConverter c = property.TypeConverter;
if (c != null && c.CanConvertFrom(typeof(string)) && c.CanConvertTo(typeof(string)))
return typeof(TextBoxEditor);
else
return typeof(FallbackEditor);
}
}
/// <summary>
/// Registers property editors defined in the specified assembly.
/// </summary>
public void RegisterAssembly(Assembly assembly)
{
if (assembly == null)
throw new ArgumentNullException("assembly");
foreach (Type type in assembly.GetExportedTypes()) {
foreach (TypeEditorAttribute editorAttribute in type.GetCustomAttributes(typeof(TypeEditorAttribute), false)) {
CheckValidEditor(type);
_typeEditors[editorAttribute.SupportedPropertyType] = type;
}
foreach (PropertyEditorAttribute editorAttribute in type.GetCustomAttributes(typeof(PropertyEditorAttribute), false)) {
CheckValidEditor(type);
string propertyName = editorAttribute.PropertyDeclaringType.FullName + "." + editorAttribute.PropertyName;
_propertyEditors[propertyName] = type;
}
}
}
static readonly Type[] typeArrayWithPropertyEditorDataProperty = { typeof(IPropertyEditorDataProperty) };
static void CheckValidEditor(Type type)
{
if (!typeof(UIElement).IsAssignableFrom(type)) {
throw new DesignerException("Editor types must derive from UIElement!");
}
if (type.GetConstructor(typeArrayWithPropertyEditorDataProperty) == null) {
throw new DesignerException("Editor types must have a constructor that takes a IPropertyEditorDataProperty as argument!");
}
}
}
}

69
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/FallbackEditor.cs

@ -1,69 +0,0 @@ @@ -1,69 +0,0 @@
// <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.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// The type editor used when no other type editor could be found.
/// </summary>
[TypeEditor(typeof(object))]
public sealed class FallbackEditor : TextBlock
{
readonly IPropertyEditorDataProperty property;
/// <summary>
/// Creates a new FallbackEditor instance for the specified property.
/// </summary>
public FallbackEditor(IPropertyEditorDataProperty property)
{
if (property == null)
throw new ArgumentNullException("property");
this.property = property;
this.TextTrimming = TextTrimming.CharacterEllipsis;
PropertyEditorBindingHelper.AddValueChangedEventHandler(this, property, OnValueChanged);
OnValueChanged(null, null);
}
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
void OnValueChanged(object sender, EventArgs e)
{
if (property.IsSet) {
this.FontWeight = FontWeights.Bold;
} else {
this.FontWeight = FontWeights.Regular;
}
if (property.IsAmbiguous) {
this.Text = "";
} else {
object val = property.Value;
if (val == null) {
this.Text = "null";
this.FontStyle = FontStyles.Italic;
} else {
this.FontStyle = FontStyles.Normal;
try {
this.Text = val.ToString();
} catch (Exception ex) {
this.FontWeight = FontWeights.Regular;
Inlines.Clear();
Inlines.Add(new Italic(new Run(ex.GetType().Name)));
Inlines.Add(" ");
Inlines.Add(ex.Message);
}
}
}
}
}
}

178
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/IPropertyEditorDataSource.cs

@ -1,178 +0,0 @@ @@ -1,178 +0,0 @@
// <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.ComponentModel;
using System.Windows.Media;
using System.Windows;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// Interface for data sources used by the property editor to display the list of properties.
/// </summary>
public interface IPropertyEditorDataSource
{
/// <summary>
/// Gets/Sets the name of the item. Returns null when the item does not support having a name.
/// </summary>
string Name { get; set; }
/// <summary>
/// Is raised whenever the Name property changes value.
/// </summary>
event EventHandler NameChanged;
/// <summary>
/// Gets the type of the item (for display only).
/// </summary>
string Type { get; }
/// <summary>
/// Gets the icon of the item (for display only)
/// </summary>
ImageSource Icon { get; }
/// <summary>
/// Gets the collection of properties.
/// </summary>
ICollection<IPropertyEditorDataProperty> Properties { get; }
/// <summary>
/// Gets the collection of events.
/// </summary>
ICollection<IPropertyEditorDataEvent> Events { get; }
/// <summary>
/// Gets if adding attached properties is supported.
/// </summary>
bool CanAddAttachedProperties { get; }
/// <summary>
/// Gets the service container attached to this data source.
/// </summary>
ServiceContainer Services { get; }
/// <summary>
/// Gets a brush used as a preview for the data source.
/// </summary>
Brush CreateThumbnailBrush();
}
/// <summary>
/// Represents a property or event inside a <see cref="IPropertyEditorDataSource"/>.
/// </summary>
public interface IPropertyEditorDataMember
{
/// <summary>
/// Gets the data source that own this property.
/// </summary>
IPropertyEditorDataSource OwnerDataSource { get; }
/// <summary>
/// Gets the name of the property.
/// </summary>
string Name { get; }
/// <summary>
/// Gets the type that declares the property.
/// </summary>
Type DeclaringType { get; }
/// <summary>
/// Gets the type of the property value / the type of the event delegate.
/// </summary>
Type ReturnType { get; }
/// <summary>
/// Gets the description of the property. The returned object should be something that
/// can be used as Content for a WPF tooltip.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate")]
object GetDescription(); // is not a property because it can create a new instance on every call
}
/// <summary>
/// Represents a property inside a <see cref="IPropertyEditorDataSource"/>.
/// </summary>
public interface IPropertyEditorDataProperty : IPropertyEditorDataMember
{
/// <summary>
/// Gets the category this property uses.
/// </summary>
string Category { get; }
/// <summary>
/// Gets the type converter used to convert property values to/from string.
/// </summary>
TypeConverter TypeConverter { get; }
/// <summary>
/// Gets/Sets if the property has been assigned a local value.
/// Setting this property to false has the effect of resetting the value, setting it to true
/// copies the default value to a local value.
/// </summary>
bool IsSet { get; set; }
/// <summary>
/// Is raised when the IsSet property has changed.
/// </summary>
event EventHandler IsSetChanged;
/// <summary>
/// Gets if the property value is ambiguous.
/// </summary>
bool IsAmbiguous { get; }
/// <summary>
/// Gets/Sets the value of the property.
/// </summary>
object Value { get; set; }
/// <summary>
/// Is raised when the Value property has changed.
/// </summary>
event EventHandler ValueChanged;
/// <summary>
/// Gets if using a custom expression is supported.
/// </summary>
bool CanUseCustomExpression { get; }
/// <summary>
/// Sets a custom expression.
/// </summary>
void SetCustomExpression(string expression);
/// <summary>
/// Creates a UIElement that can edit the property value.
/// </summary>
UIElement CreateEditor();
}
/// <summary>
/// Represents an event inside a <see cref="IPropertyEditorDataSource"/>.
/// </summary>
public interface IPropertyEditorDataEvent : IPropertyEditorDataMember
{
/// <summary>
/// Gets/Sets the name of the event handler.
/// </summary>
string HandlerName { get; set; }
/// <summary>
/// Is raised when the HandlerName property has changed.
/// </summary>
event EventHandler HandlerNameChanged;
/// <summary>
/// Goes to the event handler, creating it when necessary.
/// </summary>
void GoToHandler();
}
}

230
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultipleSelectionDataProperty.cs

@ -1,230 +0,0 @@ @@ -1,230 +0,0 @@
// <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.Diagnostics;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
sealed class MultipleSelectionDataProperty : IPropertyEditorDataProperty
{
readonly MultipleSelectionDataSource ownerDataSource;
readonly IPropertyEditorDataProperty[] data;
public MultipleSelectionDataProperty(MultipleSelectionDataSource ownerDataSource, IPropertyEditorDataProperty[] data)
{
Debug.Assert(ownerDataSource != null);
Debug.Assert(data != null);
Debug.Assert(data.Length >= 2);
this.ownerDataSource = ownerDataSource;
this.data = data;
}
#region IsSet + IsSetChanged
EventHandler isSetChangedHandlers;
bool cachedIsSet;
public event EventHandler IsSetChanged {
add {
if (isSetChangedHandlers == null) {
cachedIsSet = GetIsSetInternal();
foreach (IPropertyEditorDataProperty p in data) {
p.IsSetChanged += OnIsSetChanged;
}
}
isSetChangedHandlers += value;
}
remove {
isSetChangedHandlers -= value;
if (isSetChangedHandlers == null) {
foreach (IPropertyEditorDataProperty p in data) {
p.IsSetChanged -= OnIsSetChanged;
}
}
}
}
void OnIsSetChanged(object sender, EventArgs e)
{
bool newIsSet = GetIsSetInternal();
if (newIsSet != cachedIsSet) {
cachedIsSet = newIsSet;
isSetChangedHandlers(this, e);
}
}
bool GetIsSetInternal()
{
foreach (IPropertyEditorDataProperty p in data) {
if (p.IsSet)
return true;
}
return false;
}
public bool IsSet {
get {
if (isSetChangedHandlers != null)
return cachedIsSet;
else
return GetIsSetInternal();
}
set {
foreach (IPropertyEditorDataProperty p in data) {
p.IsSet = value;
}
}
}
#endregion
#region Value
EventHandler valueChangedHandlers;
object cachedValue;
bool cachedIsAmbiguous;
/// <summary>0 = don't prevent, 1 = prevent, 2 = prevented</summary>
byte preventOnValueChanged;
public event EventHandler ValueChanged {
add {
if (valueChangedHandlers == null) {
cachedValue = GetValueInternal();
cachedIsAmbiguous = GetIsAmbiguousInternal();
foreach (IPropertyEditorDataProperty p in data) {
p.ValueChanged += OnValueChanged;
}
}
valueChangedHandlers += value;
}
remove {
valueChangedHandlers -= value;
if (valueChangedHandlers == null) {
foreach (IPropertyEditorDataProperty p in data) {
p.ValueChanged -= OnValueChanged;
}
}
}
}
void OnValueChanged(object sender, EventArgs e)
{
if (preventOnValueChanged > 0) {
preventOnValueChanged = 2;
return;
}
cachedValue = GetValueInternal();
cachedIsAmbiguous = GetIsAmbiguousInternal();
valueChangedHandlers(this, e);
}
object GetValueInternal()
{
object val = data[0].Value;
for (int i = 1; i < data.Length; i++) {
if (!object.Equals(data[i].Value, val))
return null;
}
return val;
}
bool GetIsAmbiguousInternal()
{
object val = data[0].Value;
for (int i = 1; i < data.Length; i++) {
if (!object.Equals(data[i].Value, val))
return true;
}
return false;
}
public object Value {
get {
if (valueChangedHandlers != null)
return cachedValue;
else
return GetValueInternal();
}
set {
preventOnValueChanged = 1;
foreach (IPropertyEditorDataProperty p in data) {
p.Value = value;
}
if (preventOnValueChanged == 2) {
preventOnValueChanged = 0;
OnValueChanged(null, EventArgs.Empty);
}
preventOnValueChanged = 0;
}
}
public bool IsAmbiguous {
get {
if (valueChangedHandlers != null)
return cachedIsAmbiguous;
else
return GetIsAmbiguousInternal();
}
}
#endregion
public IPropertyEditorDataSource OwnerDataSource {
get { return ownerDataSource; }
}
public string Category {
get { return data[0].Category; }
}
public string Name {
get { return data[0].Name; }
}
public Type ReturnType {
get { return data[0].ReturnType; }
}
public Type DeclaringType {
get { return data[0].DeclaringType; }
}
public System.ComponentModel.TypeConverter TypeConverter {
get { return data[0].TypeConverter; }
}
public object GetDescription()
{
return data[0].GetDescription();
}
public bool CanUseCustomExpression {
get {
foreach (IPropertyEditorDataProperty p in data) {
if (!p.CanUseCustomExpression)
return false;
}
return true;
}
}
public void SetCustomExpression(string expression)
{
foreach (IPropertyEditorDataProperty p in data) {
p.SetCustomExpression(expression);
}
}
public System.Windows.UIElement CreateEditor()
{
EditorManager manager = ownerDataSource.Services.GetService<EditorManager>();
if (manager != null) {
return manager.CreateEditor(this);
} else {
return new FallbackEditor(this);
}
}
}
}

144
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultipleSelectionDataSource.cs

@ -1,144 +0,0 @@ @@ -1,144 +0,0 @@
// <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.Linq;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// Implements IPropertyEditorDataSource by combining the information from multiple data sources.
/// </summary>
public sealed class MultipleSelectionDataSource : IPropertyEditorDataSource
{
/// <summary>
/// Creates a data source for a collection of data sources.
/// </summary>
/// <param name="services">The service container to use.</param>
/// <param name="sources">The collection of data sources.</param>
/// <returns>
/// <c>null</c>, if sources is <c>null</c> or empty.
/// <c>sources[0]</c>, if sources.Count == 1.
/// A new MultiSelectionDataSource, if sources.Count >= 2.
/// </returns>
public static IPropertyEditorDataSource CreateDataSource(ServiceContainer services, ICollection<IPropertyEditorDataSource> sources)
{
if (sources == null || sources.Count == 0) {
return null;
} else if (sources.Count == 1) {
foreach (IPropertyEditorDataSource s in sources) {
return s;
}
throw new InvalidOperationException();
} else {
return new MultipleSelectionDataSource(services, sources);
}
}
readonly ServiceContainer services;
readonly IPropertyEditorDataSource[] data;
readonly List<IPropertyEditorDataProperty> properties = new List<IPropertyEditorDataProperty>();
/// <summary>
/// Creates a new MultiSelectionDataSource instance.
/// </summary>
public MultipleSelectionDataSource(ServiceContainer services, ICollection<IPropertyEditorDataSource> sources)
{
this.services = services;
if (sources == null)
throw new ArgumentNullException("sources");
data = sources.ToArray();
if (data.Length < 2)
throw new ArgumentException("The collection must have at least 2 items!");
foreach (IPropertyEditorDataProperty property in data[0].Properties) {
IPropertyEditorDataProperty[] properties = new IPropertyEditorDataProperty[data.Length];
properties[0] = property;
for (int i = 1; i < data.Length; i++) {
foreach (IPropertyEditorDataProperty p in data[i].Properties) {
if (p.Name == property.Name && p.ReturnType == property.ReturnType) {
properties[i] = p;
break;
}
}
if (properties[i] == null) {
properties = null; // could not find the property for all data sources
break;
}
}
if (properties != null) {
this.properties.Add(new MultipleSelectionDataProperty(this, properties));
}
}
}
/// <summary>
/// Is never raised because Name cannot change.
/// </summary>
public event EventHandler NameChanged {
add { } remove { }
}
/// <summary>
/// Always returns null. The setter throws an exception.
/// </summary>
public string Name {
get { return null; }
set { throw new NotSupportedException(); }
}
/// <summary>
/// Gets the type of the selected objects.
/// </summary>
public string Type {
get { return "multiple selection"; }
}
/// <summary>
/// Gets the icon of the selected objects.
/// </summary>
public System.Windows.Media.ImageSource Icon {
get { return null; }
}
/// <summary>
/// Gets the collection of properties.
/// </summary>
public ICollection<IPropertyEditorDataProperty> Properties {
get { return properties.AsReadOnly(); }
}
/// <summary>
/// Gets if adding attached properties is supported.
/// </summary>
public bool CanAddAttachedProperties {
get { return false; }
}
/// <summary>
/// Gets the service container used by this data source.
/// </summary>
public ServiceContainer Services {
get { return services; }
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public Brush CreateThumbnailBrush()
{
return null;
}
/// <summary>See <see cref="IPropertyEditorDataSource"/></summary>
public ICollection<IPropertyEditorDataEvent> Events {
get { return new IPropertyEditorDataEvent[0]; }
}
}
}

50
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/PropertyEditorAttribute.cs

@ -1,50 +0,0 @@ @@ -1,50 +0,0 @@
// <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.PropertyEditor
{
/// <summary>
/// Attribute to specify that the decorated class is a editor for the specified property.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple=true, Inherited=false)]
public sealed class PropertyEditorAttribute : Attribute
{
readonly Type propertyDeclaringType;
readonly string propertyName;
/// <summary>
/// Creates a new PropertyEditorAttribute that specifies that the decorated class is a editor
/// for the "<paramref name="propertyDeclaringType"/>.<paramref name="propertyName"/>".
/// </summary>
public PropertyEditorAttribute(Type propertyDeclaringType, string propertyName)
{
if (propertyDeclaringType == null)
throw new ArgumentNullException("propertyDeclaringType");
if (propertyName == null)
throw new ArgumentNullException("propertyName");
this.propertyDeclaringType = propertyDeclaringType;
this.propertyName = propertyName;
}
/// <summary>
/// Gets the type that declares the property that the decorated editor supports.
/// </summary>
public Type PropertyDeclaringType {
get { return propertyDeclaringType; }
}
/// <summary>
/// Gets the name of the property that the decorated editor supports.
/// </summary>
public string PropertyName {
get { return propertyName; }
}
}
}

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

@ -1,137 +0,0 @@ @@ -1,137 +0,0 @@
// <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>
// Enable additional Debug.WriteLines for Loading/Unloading event handlers
//#define PropertyEditorBindingHelperDebugging
using System;
using System.Diagnostics;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using System.ComponentModel;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// Provides a static method to create a binding between a dependency property
/// and a data property.
/// </summary>
public static class PropertyEditorBindingHelper
{
/// <summary>
/// Registers a value changed event handler for the data property that gets unregistered when the
/// editor FrameworkElement is unloaded.
/// </summary>
public static void AddValueChangedEventHandler(FrameworkElement editor, IPropertyEditorDataProperty dataProperty, EventHandler handler)
{
if (editor == null)
throw new ArgumentNullException("editor");
if (dataProperty == null)
throw new ArgumentNullException("dataProperty");
if (handler == null)
throw new ArgumentNullException("handler");
bool isAttached = false;
editor.Loaded += delegate {
if (!isAttached) {
isAttached = true;
dataProperty.ValueChanged += handler;
}
};
editor.Unloaded += delegate {
if (isAttached) {
isAttached = false;
dataProperty.ValueChanged -= handler;
}
};
if (editor.IsLoaded) {
isAttached = true;
dataProperty.ValueChanged += handler;
}
}
/// <summary>
/// Binds editor.property to dataProperty.Value.
/// </summary>
public static Binding CreateBinding(FrameworkElement editor, IPropertyEditorDataProperty dataProperty)
{
if (editor == null)
throw new ArgumentNullException("editor");
if (dataProperty == null)
throw new ArgumentNullException("dataProperty");
#if PropertyEditorBindingHelperDebugging
Debug.WriteLine("Create CustomBinding");
#endif
CustomBinding customBinding = new CustomBinding(dataProperty);
editor.Loaded += customBinding.OnLoaded;
editor.Unloaded += customBinding.OnUnloaded;
if (editor.IsLoaded) {
customBinding.OnLoaded(editor, null);
}
Binding b = new Binding("BoundValue");
b.Source = customBinding;
b.ConverterCulture = CultureInfo.InvariantCulture;
return b;
}
sealed class CustomBinding : INotifyPropertyChanged
{
readonly IPropertyEditorDataProperty dataProperty;
bool isLoaded;
public CustomBinding(IPropertyEditorDataProperty dataProperty)
{
this.dataProperty = dataProperty;
}
internal void OnLoaded(object sender, RoutedEventArgs e)
{
#if PropertyEditorBindingHelperDebugging
Debug.WriteLine("CustomBinding.OnLoaded (isLoaded=" + isLoaded + ")");
#endif
if (!isLoaded) {
isLoaded = true;
dataProperty.ValueChanged += OnValueChanged;
}
}
internal void OnUnloaded(object sender, RoutedEventArgs e)
{
#if PropertyEditorBindingHelperDebugging
Debug.WriteLine("CustomBinding.OnUnloaded (isLoaded=" + isLoaded + ")");
#endif
if (isLoaded) {
isLoaded = false;
dataProperty.ValueChanged -= OnValueChanged;
}
}
// Used by the Binding using Reflection.
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
public object BoundValue {
get { return dataProperty.Value; }
set { dataProperty.Value = value; }
}
public event PropertyChangedEventHandler PropertyChanged;
void OnValueChanged(object sender, EventArgs e)
{
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("BoundValue"));
}
}
}
}
}

109
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/ProxyPropertyEditorDataProperty.cs

@ -1,109 +0,0 @@ @@ -1,109 +0,0 @@
// <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.PropertyEditor
{
/// <summary>
/// Implements IPropertyEditorDataProperty by forwarding all calls to another IPropertyEditorDataProperty.
/// </summary>
public abstract class ProxyPropertyEditorDataProperty : IPropertyEditorDataProperty
{
readonly IPropertyEditorDataProperty data;
/// <summary></summary>
protected ProxyPropertyEditorDataProperty(IPropertyEditorDataProperty data)
{
if (data == null)
throw new ArgumentNullException("data");
this.data = data;
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual event EventHandler IsSetChanged {
add { data.IsSetChanged += value; }
remove { data.IsSetChanged -= value; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual event EventHandler ValueChanged {
add { data.ValueChanged += value; }
remove { data.ValueChanged -= value; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual IPropertyEditorDataSource OwnerDataSource {
get { return data.OwnerDataSource; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual string Category {
get { return data.Category; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual string Name {
get { return data.Name; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual Type ReturnType {
get { return data.ReturnType; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual Type DeclaringType {
get { return data.DeclaringType; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual System.ComponentModel.TypeConverter TypeConverter {
get { return data.TypeConverter; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual bool IsSet {
get { return data.IsSet; }
set { data.IsSet = value; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual bool IsAmbiguous {
get { return data.IsAmbiguous; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual object Value {
get { return data.Value; }
set { data.Value = value; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual bool CanUseCustomExpression {
get { return data.CanUseCustomExpression; }
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual object GetDescription()
{
return data.GetDescription();
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual void SetCustomExpression(string expression)
{
data.SetCustomExpression(expression);
}
/// <summary>See <see cref="IPropertyEditorDataProperty"/></summary>
public virtual System.Windows.UIElement CreateEditor()
{
return data.CreateEditor();
}
}
}

34
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/StandardValuesComboBoxEditor.cs

@ -1,34 +0,0 @@ @@ -1,34 +0,0 @@
// <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.Diagnostics;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// Type editor used to edit enum properties.
/// </summary>
sealed class StandardValuesComboBoxEditor : ComboBox
{
/// <summary>
/// Creates a new EnumEditor instance.
/// </summary>
public StandardValuesComboBoxEditor(IPropertyEditorDataProperty property)
{
foreach (object o in property.TypeConverter.GetStandardValues()) {
this.Items.Add(o);
}
SetBinding(ComboBox.SelectedItemProperty, PropertyEditorBindingHelper.CreateBinding(this, property));
}
}
}

163
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/TextBoxEditor.cs

@ -1,163 +0,0 @@ @@ -1,163 +0,0 @@
// <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.ComponentModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Data;
using System.Windows.Media;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
using System.Windows.Threading;
using System.Windows.Input;
namespace ICSharpCode.WpfDesign.PropertyEditor
{
/// <summary>
/// Type editor used to edit properties using a text box and the type's default type converter.
/// </summary>
public sealed class TextBoxEditor : TextBox
{
readonly IPropertyEditorDataProperty property;
bool isDirty;
bool hasError;
/// <summary>
/// The property edited by the TextBoxEditor.
/// </summary>
public IPropertyEditorDataProperty Property {
get { return property; }
}
/// <summary>
/// Creates a new TextBoxEditor instance.
/// </summary>
public TextBoxEditor(IPropertyEditorDataProperty property)
{
if (property == null)
throw new ArgumentNullException("property");
this.property = property;
UpdateFromSource();
PropertyEditorBindingHelper.AddValueChangedEventHandler(
this, property, delegate { UpdateFromSource(); }
);
}
void UpdateFromSource()
{
if (property.IsAmbiguous) {
this.Text = "";
this.Background = SystemColors.ControlBrush;
} else {
this.Text = property.TypeConverter.ConvertToInvariantString(property.Value);
}
hasError = false;
isDirty = false;
if (property.IsSet) {
this.Foreground = SystemColors.WindowTextBrush;
} else {
this.Foreground = SystemColors.GrayTextBrush;
}
}
void SaveValueToSource()
{
isDirty = false;
hasError = false;
try {
property.Value = property.TypeConverter.ConvertFromInvariantString(this.Text);
} catch (Exception) {
hasError = true;
throw;
}
if (ValueSaved != null)
ValueSaved(this, EventArgs.Empty);
}
/// <summary>
/// Raised when the user changes the property value using this text box.
/// </summary>
public event EventHandler ValueSaved;
static UIElement DescribeError(Exception ex)
{
return new TextBlock(new Run(ex.Message));
}
static void ShowError(ServiceContainer serviceContainer, FrameworkElement control, UIElement errorDescription)
{
IErrorService errorService = null;
if (serviceContainer != null)
errorService = serviceContainer.GetService<IErrorService>();
if (errorService != null) {
errorService.ShowErrorTooltip(control, errorDescription);
}
}
/// <summary/>
protected override void OnTextChanged(TextChangedEventArgs e)
{
isDirty = true;
this.Background = SystemColors.WindowBrush;
this.Foreground = SystemColors.WindowTextBrush;
base.OnTextChanged(e);
}
/// <summary/>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
protected override void OnLostFocus(RoutedEventArgs e)
{
if (isDirty) {
try {
SaveValueToSource();
} catch (Exception ex) {
Dispatcher.BeginInvoke(
DispatcherPriority.Normal, new Action<Exception>(
delegate (Exception exception) {
if (Focus()) {
ShowError(property.OwnerDataSource.Services, this, DescribeError(exception));
}
}), ex);
}
} else if (hasError) {
UpdateFromSource();
}
base.OnLostFocus(e);
}
/// <summary/>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
protected override void OnKeyDown(KeyEventArgs e)
{
base.OnKeyDown(e);
if (e.Handled) return;
if (e.Key == Key.Enter) {
string oldText = this.Text;
try {
SaveValueToSource();
} catch (Exception ex) {
ShowError(property.OwnerDataSource.Services, this, DescribeError(ex));
}
if (this.Text != oldText) {
this.SelectAll();
}
e.Handled = true;
} else if (e.Key == Key.Escape) {
string oldText = this.Text;
UpdateFromSource();
if (this.Text != oldText) {
this.SelectAll();
}
e.Handled = true;
}
}
}
}

39
src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/TypeEditorAttribute.cs

@ -1,39 +0,0 @@ @@ -1,39 +0,0 @@
// <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.PropertyEditor
{
/// <summary>
/// Attribute to specify that the decorated class is a editor for properties with the specified
/// return type.
/// </summary>
[AttributeUsage(AttributeTargets.Class, AllowMultiple=true, Inherited=false)]
public sealed class TypeEditorAttribute : Attribute
{
readonly Type supportedPropertyType;
/// <summary>
/// Creates a new TypeEditorAttribute that specifies that the decorated class is a editor
/// for properties with the return type "<paramref name="supportedPropertyType"/>".
/// </summary>
public TypeEditorAttribute(Type supportedPropertyType)
{
if (supportedPropertyType == null)
throw new ArgumentNullException("supportedPropertyType");
this.supportedPropertyType = supportedPropertyType;
}
/// <summary>
/// Gets the supported property type.
/// </summary>
public Type SupportedPropertyType {
get { return supportedPropertyType; }
}
}
}
Loading…
Cancel
Save