Browse Source
git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2254 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61shortcuts
26 changed files with 962 additions and 66 deletions
@ -0,0 +1,65 @@
@@ -0,0 +1,65 @@
|
||||
// <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 System.Windows.Controls; |
||||
using System.Windows.Documents; |
||||
using ICSharpCode.WpfDesign.PropertyEditor; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Controls |
||||
{ |
||||
// Text block used in the first column of the PropertyGridView.
|
||||
// Creates ToolTip and ContextMenu objects on-demand.
|
||||
sealed class PropertyNameTextBlock : TextBlock |
||||
{ |
||||
readonly IPropertyEditorDataProperty property; |
||||
readonly TextBlock toolTipTextBlock; |
||||
bool toolTipTextBlockInitialized; |
||||
internal DependencyPropertyDotButton ContextMenuProvider; |
||||
|
||||
public PropertyNameTextBlock(IPropertyEditorDataProperty property) |
||||
: base(new Run(property.Name)) |
||||
{ |
||||
this.property = property; |
||||
this.TextAlignment = TextAlignment.Right; |
||||
this.TextTrimming = TextTrimming.CharacterEllipsis; |
||||
|
||||
this.ToolTip = toolTipTextBlock = new TextBlock(); |
||||
} |
||||
|
||||
protected override void OnToolTipOpening(ToolTipEventArgs e) |
||||
{ |
||||
CreateToolTip(); |
||||
base.OnToolTipOpening(e); |
||||
} |
||||
|
||||
protected override void OnContextMenuOpening(ContextMenuEventArgs e) |
||||
{ |
||||
if (ContextMenuProvider != null) { |
||||
this.ContextMenu = ContextMenuProvider.CreateContextMenu(); |
||||
} |
||||
base.OnContextMenuOpening(e); |
||||
} |
||||
|
||||
void CreateToolTip() |
||||
{ |
||||
if (toolTipTextBlockInitialized) |
||||
return; |
||||
toolTipTextBlockInitialized = true; |
||||
toolTipTextBlock.TextAlignment = TextAlignment.Left; |
||||
toolTipTextBlock.Inlines.Add(new Bold(new Run(property.Name))); |
||||
if (property.ReturnType != null) { |
||||
toolTipTextBlock.Inlines.Add(" (" + property.ReturnType.Name + ")"); |
||||
} |
||||
if (!string.IsNullOrEmpty(property.Description)) { |
||||
toolTipTextBlock.Inlines.Add(new LineBreak()); |
||||
toolTipTextBlock.Inlines.Add(property.Description); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,35 @@
@@ -0,0 +1,35 @@
|
||||
// <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; |
||||
using ICSharpCode.WpfDesign.PropertyEditor; |
||||
|
||||
namespace ICSharpCode.WpfDesign.Designer.Controls.TypeEditors |
||||
{ |
||||
/// <summary>
|
||||
/// Type editor used to edit Brush properties.
|
||||
/// </summary>
|
||||
[TypeEditor(typeof(Brush))] |
||||
public sealed class BrushEditor : Border |
||||
{ |
||||
/// <summary>
|
||||
/// Creates a new BooleanEditor instance.
|
||||
/// </summary>
|
||||
public BrushEditor(IPropertyEditorDataProperty property) |
||||
{ |
||||
this.BorderBrush = Brushes.Black; |
||||
this.BorderThickness = new Thickness(1); |
||||
SetBinding(BackgroundProperty, PropertyEditorBindingHelper.CreateBinding(this, property)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,30 @@
@@ -0,0 +1,30 @@
|
||||
// <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)); |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,111 @@
@@ -0,0 +1,111 @@
|
||||
// <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.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) |
||||
{ |
||||
return (UIElement)Activator.CreateInstance(GetEditorType(property), property); |
||||
} |
||||
|
||||
/// <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) |
||||
{ |
||||
Type returnType = property.ReturnType; |
||||
if (returnType.IsEnum) { |
||||
return typeof(EnumEditor); |
||||
} 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!"); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,31 @@
@@ -0,0 +1,31 @@
|
||||
// <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 EnumEditor : ComboBox |
||||
{ |
||||
/// <summary>
|
||||
/// Creates a new EnumEditor instance.
|
||||
/// </summary>
|
||||
public EnumEditor(IPropertyEditorDataProperty property) |
||||
{ |
||||
|
||||
} |
||||
} |
||||
} |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
// <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 |
||||
{ |
||||
/// <summary>
|
||||
/// Creates a new FallbackEditor instance for the specified property.
|
||||
/// </summary>
|
||||
public FallbackEditor(IPropertyEditorDataProperty property) |
||||
{ |
||||
if (property == null) |
||||
throw new ArgumentNullException("property"); |
||||
|
||||
this.TextTrimming = TextTrimming.CharacterEllipsis; |
||||
if (property.IsSet) { |
||||
this.FontWeight = FontWeights.Bold; |
||||
} |
||||
object val = property.Value; |
||||
if (val == null) { |
||||
this.Text = "null"; |
||||
this.FontStyle = FontStyles.Italic; |
||||
} else { |
||||
try { |
||||
this.Text = val.ToString(); |
||||
} catch (Exception ex) { |
||||
this.FontWeight = FontWeights.Regular; |
||||
Inlines.Add(new Italic(new Run(ex.GetType().Name))); |
||||
Inlines.Add(" "); |
||||
Inlines.Add(ex.Message); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,50 @@
@@ -0,0 +1,50 @@
|
||||
// <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; } |
||||
} |
||||
} |
||||
} |
||||
|
@ -0,0 +1,79 @@
@@ -0,0 +1,79 @@
|
||||
// <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.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>
|
||||
/// 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"); |
||||
|
||||
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; |
||||
|
||||
public CustomBinding(IPropertyEditorDataProperty dataProperty) |
||||
{ |
||||
this.dataProperty = dataProperty; |
||||
} |
||||
|
||||
internal void OnLoaded(object sender, RoutedEventArgs e) |
||||
{ |
||||
dataProperty.ValueChanged += OnValueChanged; |
||||
} |
||||
|
||||
internal void OnUnloaded(object sender, RoutedEventArgs e) |
||||
{ |
||||
dataProperty.ValueChanged -= OnValueChanged; |
||||
} |
||||
|
||||
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")); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
// <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.Documents; |
||||
|
||||
namespace ICSharpCode.WpfDesign.PropertyEditor |
||||
{ |
||||
/// <summary>
|
||||
/// Type editor used to edit properties using a text box and the type's default type converter.
|
||||
/// </summary>
|
||||
sealed class TextBoxEditor : TextBox |
||||
{ |
||||
/// <summary>
|
||||
/// Creates a new TextBoxEditor instance.
|
||||
/// </summary>
|
||||
public TextBoxEditor(IPropertyEditorDataProperty property) |
||||
{ |
||||
Binding b = PropertyEditorBindingHelper.CreateBinding(this, property); |
||||
b.Converter = new ToStringConverter(property.TypeConverter); |
||||
SetBinding(TextProperty, b); |
||||
} |
||||
|
||||
sealed class ToStringConverter : IValueConverter |
||||
{ |
||||
readonly TypeConverter converter; |
||||
|
||||
public ToStringConverter(TypeConverter converter) |
||||
{ |
||||
this.converter = converter; |
||||
} |
||||
|
||||
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
{ |
||||
return converter.ConvertToString(null, culture, value); |
||||
} |
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) |
||||
{ |
||||
return converter.ConvertFromString(null, culture, (string)value); |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
// <file>
|
||||
// <copyright see="prj:///doc/copyright.txt"/>
|
||||
// <license see="prj:///doc/license.txt"/>
|
||||
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
|
||||
// <version>$Revision$</version>
|
||||
// </file>
|
||||
|
||||
using System; |
||||
|
||||
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…
Reference in new issue