diff --git a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/StandaloneDesigner.csproj b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/StandaloneDesigner.csproj index 80268e5206..c738fd07d7 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/StandaloneDesigner.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/StandaloneDesigner.csproj @@ -48,6 +48,7 @@ App.xaml + Code Window1.xaml @@ -57,5 +58,9 @@ {78CC29AC-CC79-4355-B1F2-97936DF198AC} WpfDesign.Designer + + {66A378A1-E9F4-4AD5-8946-D0EC06C2902F} + WpfDesign + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/StrangeDataSource.cs b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/StrangeDataSource.cs new file mode 100644 index 0000000000..9429b694b7 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/StrangeDataSource.cs @@ -0,0 +1,67 @@ +// +// +// +// +// $Revision$ +// + +using System; +using ICSharpCode.WpfDesign.PropertyEditor; +using System.Windows; +using System.Windows.Threading; + +namespace StandaloneDesigner +{ + public class StrangeDataSource : IPropertyEditorDataSource + { + string name; + + public string Name { + get { return name; } + set { + name = value; + + if (NameChanged != null) { + NameChanged(this, EventArgs.Empty); + } + } + } + + public StrangeDataSource() + { + // set the name of this data source to the current time + DispatcherTimer t = new DispatcherTimer(); + t.Interval = TimeSpan.FromSeconds(1); + t.Tick += delegate { + this.Name = DateTime.Now.ToString(); + }; + t.Start(); + } + + public event EventHandler NameChanged; + + public string Type { + get { + return "Strange"; + } + } + + public System.Windows.Media.ImageSource Icon { + get { + return null; + } + } + + public System.Collections.Generic.ICollection Properties { + get { + return new IPropertyEditorDataProperty[0]; + } + } + + public bool CanAddAttachedProperties { + get { + return false; + } + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml index 3c40956587..893096a26b 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml +++ b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml @@ -1,11 +1,20 @@  - - - + + + + + + + ]]> - - - - - - + + + + + + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs index 1b459fcc81..aea3e40c30 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/StandaloneDesigner/Window1.xaml.cs @@ -6,6 +6,9 @@ using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Markup; using System.Xml; +using ICSharpCode.WpfDesign; +using ICSharpCode.WpfDesign.Designer; +using ICSharpCode.WpfDesign.PropertyEditor; namespace StandaloneDesigner { @@ -16,17 +19,48 @@ namespace StandaloneDesigner { public Window1() { - InitializeComponent(); + try { + InitializeComponent(); + } catch (Exception ex) { + MessageBox.Show(ex.ToString()); + Close(); + } + + propertyEditor.EditedObject = new StrangeDataSource(); } + #if XAML_DEFINITIONS + // this is not compiled, but gives us code-completion inside SharpDevelop + TextBox CodeTextBox; + DesignSurface designSurface; + PropertyEditor propertyEditor; + #endif + void tabControlSelectionChanged(object sender, RoutedEventArgs e) { if (e.Source != tabControl) return; if (tabControl.SelectedItem == designTab) { designSurface.LoadDesigner(new XmlTextReader(new StringReader(CodeTextBox.Text))); + designSurface.DesignContext.Services.Selection.SelectionChanged += OnSelectionChanged; } else { + if (designSurface.DesignContext != null) { + propertyEditor.EditedObject = null; + + using (StringWriter writer = new StringWriter()) { + using (XmlTextWriter xmlWriter = new XmlTextWriter(writer)) { + xmlWriter.Formatting = Formatting.Indented; + designSurface.SaveDesigner(xmlWriter); + } + CodeTextBox.Text = writer.ToString(); + } + } designSurface.UnloadDesigner(); } } + + void OnSelectionChanged(object sender, DesignItemCollectionEventArgs e) + { + propertyEditor.EditedObject = new DesignItemDataSource(designSurface.DesignContext.Services.Selection.PrimarySelection); + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs index 80c408b216..7e56061dd4 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/AdornerLayer.cs @@ -6,11 +6,12 @@ // using System; -using System.Diagnostics; using System.Collections.Generic; +using System.Diagnostics; using System.Windows; using System.Windows.Controls; using System.Windows.Media; + using ICSharpCode.WpfDesign.Adorners; namespace ICSharpCode.WpfDesign.Designer.Controls @@ -89,7 +90,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls AdornerPanelCollection _adorners; readonly UIElement _designPanel; - #if DEBUG + #if DEBUG_ADORNERLAYER int _totalAdornerCount; #endif @@ -139,7 +140,7 @@ namespace ICSharpCode.WpfDesign.Designer.Controls this.Children.Clear(); _dict = new Dictionary(); - #if DEBUG + #if DEBUG_ADORNERLAYER _totalAdornerCount = 0; Debug.WriteLine("AdornerLayer cleared."); #endif @@ -174,8 +175,10 @@ namespace ICSharpCode.WpfDesign.Designer.Controls AddAdornerToChildren(adornerPanel); } + #if DEBUG_ADORNERLAYER Debug.WriteLine("Adorner added. AdornedElements=" + _dict.Count + ", visible adorners=" + VisualChildrenCount + ", total adorners=" + (++_totalAdornerCount)); + #endif } void AddAdornerToChildren(AdornerPanel adornerPanel) @@ -229,8 +232,10 @@ namespace ICSharpCode.WpfDesign.Designer.Controls _dict.Remove(adornerPanel.AdornedElement); } + #if DEBUG_ADORNERLAYER Debug.WriteLine("Adorner removed. AdornedElements=" + _dict.Count + ", visible adorners=" + VisualChildrenCount + ", total adorners=" + (--_totalAdornerCount)); + #endif return true; } else { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml new file mode 100644 index 0000000000..dcff320dd7 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/ControlStyles.xaml @@ -0,0 +1,89 @@ + + + + + + + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs new file mode 100644 index 0000000000..40a34399cd --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.cs @@ -0,0 +1,159 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using System.Collections.Generic; +using System.Diagnostics; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Shapes; +using ICSharpCode.WpfDesign.Designer.Controls; +using ICSharpCode.WpfDesign.PropertyEditor; + +namespace ICSharpCode.WpfDesign.Designer +{ + /// + /// Description of PropertyGrid. + /// + public partial class PropertyEditor : UserControl + { + /// + /// Dependency property for . + /// + public static readonly DependencyProperty EditedObjectProperty + = DependencyProperty.Register("EditedObject", typeof(IPropertyEditorDataSource), typeof(PropertyEditor), + new FrameworkPropertyMetadata(null, _OnEditedObjectPropertyChanged)); + + #if XAML_DEFINITIONS + // this is not compiled, but gives us code-completion inside SharpDevelop + TextBox nameTextBox; + Label typeLabel; + Image componentImage; + TextBox searchTextBox; + StackPanel contentStackPanel; + #endif + + /// + /// Creates a new PropertyGrid instance. + /// + public PropertyEditor() + { + try { + InitializeComponent(); + } catch (Exception ex) { + Debug.WriteLine(ex.ToString()); + throw; + } + PropertyEditorCategoryView v = new PropertyEditorCategoryView(); + v.Header = "Titel"; + v.Content = "Inhalt"; + contentStackPanel.Children.Add(v); + } + + /// + /// Gets/Sets the object being edited. + /// + public IPropertyEditorDataSource EditedObject { + get { return (IPropertyEditorDataSource)GetValue(EditedObjectProperty); } + set { SetValue(EditedObjectProperty, value); } + } + + /// + /// Is raised when the object being edited changes. + /// + public event EventHandler EditedObjectChanged; + + static void _OnEditedObjectPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e) + { + ((PropertyEditor)obj).OnEditedObjectPropertyChanged(e); + } + + void OnEditedObjectPropertyChanged(DependencyPropertyChangedEventArgs e) + { + ShowProperties(e.NewValue as IPropertyEditorDataSource); + if (EditedObjectChanged != null) { + EditedObjectChanged(this, EventArgs.Empty); + } + } + + void ShowPropertiesButton_Click(object sender, RoutedEventArgs e) + { + ShowProperties(this.EditedObject); + } + + void ShowEventsButton_Click(object sender, RoutedEventArgs e) + { + + } + + void ShowProperties(IPropertyEditorDataSource dataSource) + { + contentStackPanel.Children.Clear(); + if (dataSource == null) + return; + + List categories = new List(); + foreach (IPropertyEditorDataProperty p in Linq.Sort(dataSource.Properties, ComparePropertyNames)) { + PropertyEditorCategoryView cv = GetOrCreateCategory(categories, p.Category); + PropertyGridView grid = (PropertyGridView)cv.Content; + grid.AddProperty(p); + } + // Sort category titles alphabetically + categories.Sort(delegate (PropertyEditorCategoryView c1, PropertyEditorCategoryView c2) { + return c1.Header.ToString().CompareTo(c2.Header.ToString()); + }); + // Add categories to contentStackPanel + foreach (PropertyEditorCategoryView c in categories) { + contentStackPanel.Children.Add(c); + } + } + + static int ComparePropertyNames(IPropertyEditorDataProperty p1, IPropertyEditorDataProperty p2) + { + return p1.Name.CompareTo(p2.Name); + } + + static PropertyEditorCategoryView GetOrCreateCategory(List categories, string category) + { + foreach (PropertyEditorCategoryView c in categories) { + if (c.Header.ToString() == category) + return c; + } + PropertyEditorCategoryView newCategory = new PropertyEditorCategoryView(); + newCategory.Header = category; + newCategory.Content = new PropertyGridView(); + categories.Add(newCategory); + return newCategory; + } + + /* + void clearSearchButton_Click(object sender, RoutedEventArgs e) + { + searchTextBox.Text = ""; + } + */ + + void nameTextBox_SizeChanged(object sender, RoutedEventArgs e) + { + // Display componentImage only if there is enough space left. + const double minimalNameTextBoxWidth = 80; + const double switchTreshold = 5; + if (componentImage.Visibility != Visibility.Collapsed) { + if (nameTextBox.ActualWidth < minimalNameTextBoxWidth - switchTreshold) { + componentImage.Visibility = Visibility.Collapsed; + } + } else { + if (nameTextBox.ActualWidth > minimalNameTextBoxWidth + componentImage.Width + switchTreshold) { + componentImage.Visibility = Visibility.Visible; + } + } + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.xaml new file mode 100644 index 0000000000..652b1b7087 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditor.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditorCategoryView.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditorCategoryView.cs new file mode 100644 index 0000000000..ebdda1d628 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditorCategoryView.cs @@ -0,0 +1,24 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows; +using System.Windows.Controls; + +namespace ICSharpCode.WpfDesign.Designer.Controls +{ + /// + /// Control used to view a property grid category. + /// + public sealed class PropertyEditorCategoryView : HeaderedContentControl + { + static PropertyEditorCategoryView() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyEditorCategoryView), new FrameworkPropertyMetadata(typeof(PropertyEditorCategoryView))); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditorStyles.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditorStyles.xaml new file mode 100644 index 0000000000..ffa1b5a6a7 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyEditorStyles.xaml @@ -0,0 +1,34 @@ + + + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyGridView.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyGridView.cs new file mode 100644 index 0000000000..9ca44d48b7 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/PropertyEditor/PropertyGridView.cs @@ -0,0 +1,54 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Windows; +using System.Windows.Controls; +using ICSharpCode.WpfDesign.PropertyEditor; + +namespace ICSharpCode.WpfDesign.Designer.Controls +{ + /// + /// Control used to view a property grid category. + /// + public sealed class PropertyGridView : Grid + { + static PropertyGridView() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(PropertyGridView), new FrameworkPropertyMetadata(typeof(PropertyGridView))); + } + + /// + /// Creates a new PropertyGridView instance. + /// + public PropertyGridView() + { + this.ColumnDefinitions.Add(new ColumnDefinition()); + this.ColumnDefinitions.Add(new ColumnDefinition()); + this.ColumnDefinitions.Add(new ColumnDefinition()); + this.ColumnDefinitions[0].Width = new GridLength(0.45, GridUnitType.Star); + this.ColumnDefinitions[0].MinWidth = 40; + this.ColumnDefinitions[1].Width = new GridLength(0.55, GridUnitType.Star); + this.ColumnDefinitions[2].Width = new GridLength(10); + } + + /// + /// Adds a new property to the PropertyGridView. + /// + public void AddProperty(IPropertyEditorDataProperty property) + { + this.RowDefinitions.Add(new RowDefinition()); + + Label propertyNameLabel = new Label(); + propertyNameLabel.Content = property.Name; + propertyNameLabel.HorizontalContentAlignment = HorizontalAlignment.Right; + SetRow(propertyNameLabel, this.RowDefinitions.Count - 1); + SetColumn(propertyNameLabel, 0); + this.Children.Add(propertyNameLabel); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SingleVisualChildElement.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SingleVisualChildElement.cs index efc1a5497e..7febc06fe4 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SingleVisualChildElement.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/SingleVisualChildElement.cs @@ -7,7 +7,6 @@ using System; using System.Windows; -using System.Windows.Controls; using System.Windows.Media; namespace ICSharpCode.WpfDesign.Designer.Controls diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/WindowClone.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/WindowClone.cs index 5286d6a3dc..aee96b4f70 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/WindowClone.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Controls/WindowClone.cs @@ -7,15 +7,13 @@ using System; using System.ComponentModel; -using System.Windows.Controls; +using System.Diagnostics; using System.Windows; -using System.Windows.Media; -using System.Windows.Shapes; +using System.Windows.Controls; using System.Windows.Input; -using System.Windows.Controls.Primitives; -using ICSharpCode.WpfDesign.Adorners; +using System.Windows.Media; + using ICSharpCode.WpfDesign.Extensions; -using System.Diagnostics; namespace ICSharpCode.WpfDesign.Designer.Controls { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs index d1659e3fea..d112667aa7 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignPanel.cs @@ -6,15 +6,16 @@ // using System; +using System.Collections.Generic; using System.Diagnostics; using System.Windows; -using System.Windows.Input; using System.Windows.Controls; +using System.Windows.Input; using System.Windows.Media; -using System.Collections.Generic; using System.Windows.Threading; -using ICSharpCode.WpfDesign.Designer.Controls; + using ICSharpCode.WpfDesign.Adorners; +using ICSharpCode.WpfDesign.Designer.Controls; namespace ICSharpCode.WpfDesign.Designer { @@ -44,6 +45,10 @@ namespace ICSharpCode.WpfDesign.Designer public DesignPanel() { this.Focusable = true; + this.VerticalAlignment = VerticalAlignment.Top; + this.HorizontalAlignment = HorizontalAlignment.Left; + this.Margin = new Thickness(10); + _eatAllHitTestRequests = new EatAllHitTestRequests(); _eatAllHitTestRequests.IsHitTestVisible = false; _adornerLayer = new AdornerLayer(this); diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs index 4ef17d1527..05a2a9ce1b 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/DesignSurface.cs @@ -8,10 +8,8 @@ using System; using System.Windows; using System.Windows.Controls; -using System.Windows.Media; -using System.Windows.Markup; using System.Xml; -using ICSharpCode.WpfDesign.Designer.Services; + using ICSharpCode.WpfDesign.Designer.Controls; namespace ICSharpCode.WpfDesign.Designer @@ -33,6 +31,8 @@ namespace ICSharpCode.WpfDesign.Designer _scrollViewer = new ScrollViewer(); _designPanel = new DesignPanel(); _scrollViewer.Content = _designPanel; + _scrollViewer.VerticalScrollBarVisibility = ScrollBarVisibility.Visible; + _scrollViewer.HorizontalScrollBarVisibility = ScrollBarVisibility.Visible; this.VisualChild = _scrollViewer; } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs index f69fb4e711..81ee2776a0 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/SelectedElementRectangleExtension.cs @@ -6,12 +6,12 @@ // using System; +using System.Windows; using System.Windows.Media; using System.Windows.Shapes; + using ICSharpCode.WpfDesign.Adorners; using ICSharpCode.WpfDesign.Extensions; -using ICSharpCode.WpfDesign.Designer.Controls; -using System.Windows; namespace ICSharpCode.WpfDesign.Designer.Extensions { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TabItemClickableExtension.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TabItemClickableExtension.cs index 4f60ef930d..664c9cb97f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TabItemClickableExtension.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Extensions/TabItemClickableExtension.cs @@ -6,7 +6,6 @@ // using System; -using System.Windows; using System.Windows.Controls; using ICSharpCode.WpfDesign.Extensions; diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs index 63a4231a11..cc8c18fdf3 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Linq.cs @@ -19,5 +19,15 @@ namespace ICSharpCode.WpfDesign.Designer collection.CopyTo(arr, 0); return arr; } + + /// + /// Returns a sorted copy of the collection. + /// + public static ICollection Sort(ICollection collection, Comparison comparison) + { + T[] arr = ToArray(collection); + Array.Sort(arr, comparison); + return arr; + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj index f472bc9a0b..0069eaa47b 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/WpfDesign.Designer.csproj @@ -58,6 +58,9 @@ + + + @@ -82,6 +85,7 @@ + @@ -95,6 +99,11 @@ WpfDesign False + + PropertyEditor.cs + + + \ No newline at end of file diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs index d401fb2770..4890a7e73d 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlDesignItem.cs @@ -6,6 +6,7 @@ // using System; +using System.Diagnostics; using System.Windows; using ICSharpCode.WpfDesign.XamlDom; using ICSharpCode.WpfDesign.Designer.Services; @@ -42,6 +43,19 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml } } + public override string Name { + get { return null; } + set { throw new NotImplementedException(); } + } + + /// + /// Is raised when the name of the design item changes. + /// + public override event EventHandler NameChanged { + add { Debug.WriteLine("Add event handler to " + this.Component.GetType().Name); } + remove { Debug.WriteLine("Remove event handler from " + this.Component.GetType().Name); } + } + public override DesignItem Parent { get { if (_xamlObject.ParentProperty == null) diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs index c2474d5efc..639be84160 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelProperty.cs @@ -6,25 +6,46 @@ // using System; +using System.Diagnostics; using ICSharpCode.WpfDesign.XamlDom; namespace ICSharpCode.WpfDesign.Designer.Xaml { - sealed class XamlModelProperty : DesignItemProperty + sealed class XamlModelProperty : DesignItemProperty, IEquatable { readonly XamlDesignItem _designItem; readonly XamlProperty _property; public XamlModelProperty(XamlDesignItem designItem, XamlProperty property) { + Debug.Assert(designItem != null); + Debug.Assert(property != null); + this._designItem = designItem; this._property = property; } + public override bool Equals(object obj) + { + return Equals(obj as XamlModelProperty); + } + + public bool Equals(XamlModelProperty other) + { + return this._designItem == other._designItem && this._property == other._property; + } + + public override int GetHashCode() + { + return _designItem.GetHashCode() ^ _property.GetHashCode(); + } + + public override string Name { + get { return _property.PropertyName; } + } + public override bool IsCollection { - get { - return _property.IsCollection; - } + get { return _property.IsCollection; } } public override System.Collections.Generic.IList CollectionElements { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs index 465f94cd63..95f8a27fff 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/Xaml/XamlModelPropertyCollection.cs @@ -35,7 +35,7 @@ namespace ICSharpCode.WpfDesign.Designer.Xaml public override System.Collections.Generic.IEnumerator GetEnumerator() { - throw new NotImplementedException(); + yield break; } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml index 25d54acea9..b025cefb6e 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.Designer/Project/themes/generic.xaml @@ -1,84 +1,8 @@  - - - - - - - + + + + diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlConstants.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlConstants.cs index a997b94bb9..cc64d34a2f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlConstants.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlConstants.cs @@ -6,7 +6,6 @@ // using System; -using System.Collections.ObjectModel; namespace ICSharpCode.WpfDesign.XamlDom { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs index 23aac310f4..ddf0e48732 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign.XamlDom/Project/XamlDocument.cs @@ -6,8 +6,8 @@ // using System; -using System.Xml; using System.ComponentModel; +using System.Xml; namespace ICSharpCode.WpfDesign.XamlDom { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs index ca1f38dec6..cc8b9eb262 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItem.cs @@ -7,8 +7,10 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Diagnostics; using System.Windows; + using ICSharpCode.WpfDesign.Extensions; namespace ICSharpCode.WpfDesign @@ -17,7 +19,7 @@ namespace ICSharpCode.WpfDesign /// The DesignItem connects a component with the service system and the designers. /// Equivalent to Cider's ModelItem. /// - public abstract class DesignItem + public abstract class DesignItem : INotifyPropertyChanged { /// /// Gets the component this DesignSite was created for. @@ -44,6 +46,16 @@ namespace ICSharpCode.WpfDesign /// public abstract DesignItemPropertyCollection Properties { get; } + /// + /// Gets/Sets the name of the design item. + /// + public abstract string Name { get; set; } + + /// + /// Is raised when the name of the design item changes. + /// + public abstract event EventHandler NameChanged; + /// /// Gets an instance that provides convenience properties for the most-used designers. /// @@ -168,5 +180,20 @@ namespace ICSharpCode.WpfDesign return (T)obj; } #endregion + + /// + /// This event is raised whenever a model property on the DesignItem changes. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Raises the event. + /// + protected virtual void OnPropertyChanged(PropertyChangedEventArgs e) + { + if (PropertyChanged != null) { + PropertyChanged(this, e); + } + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs index 678ecc18e9..b6f741bf9e 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/DesignItemProperty.cs @@ -20,6 +20,11 @@ namespace ICSharpCode.WpfDesign /// public abstract class DesignItemProperty { + /// + /// Gets the property name. + /// + public abstract string Name { get; } + /// /// Gets if the property represents a collection. /// diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/HashSet.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/HashSet.cs index a963c79abe..451941b789 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/HashSet.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/HashSet.cs @@ -6,9 +6,8 @@ // using System; -using System.Collections.Generic; -using System.Text; using System.Collections; +using System.Collections.Generic; using System.Collections.Specialized; namespace ICSharpCode.WpfDesign diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Linq.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Linq.cs index 69a7cfdcd5..9025ed11df 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Linq.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Linq.cs @@ -13,11 +13,26 @@ namespace ICSharpCode.WpfDesign // Static helpers that should become extension methods in the future static class Linq { - public static T[] ToArray(ICollection collection) + public static T[] ToArray(ICollection collection) where T : class { T[] arr = new T[collection.Count]; collection.CopyTo(arr, 0); return arr; } + + /// + /// Outputs distinct elements only, filtering all duplicates. + /// + public static IEnumerable Distinct(IEnumerable input) where T : class + { + // store elements already seen + HashSet elements = new HashSet(); + + foreach (T element in input) { + if (elements.Add(element)) { + yield return element; + } + } + } } } diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataProperty.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataProperty.cs new file mode 100644 index 0000000000..62d8f17ef7 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataProperty.cs @@ -0,0 +1,82 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Diagnostics; + +namespace ICSharpCode.WpfDesign.PropertyEditor +{ + /// + /// wraps a DesignItemDataProperty for the property editor/grid. + /// + sealed class DesignItemDataProperty : IPropertyEditorDataProperty + { + readonly DesignItemDataSource ownerDataSource; + readonly DesignItemProperty property; + + internal DesignItemDataProperty(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 Category { + get { return "Misc"; } + } + + public string Name { + get { return property.Name; } + } + + public string Description { + get { return "Description for " + property.Name; } + } + + 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 object Value { + get { + return property.ValueOnInstance; + } + set { + property.SetValue(value); + } + } + + public bool CanUseCustomExpression { + get { + return true; + } + } + + public void SetCustomExpression(string expression) + { + throw new NotImplementedException(); + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataSource.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataSource.cs new file mode 100644 index 0000000000..791dbba2b9 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/DesignItemDataSource.cs @@ -0,0 +1,96 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.ComponentModel; +using System.Windows; +using System.Windows.Media; +using System.Collections.Generic; + +namespace ICSharpCode.WpfDesign.PropertyEditor +{ + /// + /// Implements IPropertyEditorDataSource accessing the properties on a DesignItem. + /// + public sealed class DesignItemDataSource : IPropertyEditorDataSource + { + readonly DesignItem item; + readonly List properties = new List(); + + /// + /// Constructs a new DesignItemDataSource for the specified design item. + /// + public DesignItemDataSource(DesignItem item) + { + if (item == null) + throw new ArgumentNullException("item"); + this.item = item; + + List designItemProperties = new List(); + foreach (PropertyDescriptor p in TypeDescriptor.GetProperties(item.Component)) { + if (!p.IsBrowsable) continue; + if (p.IsReadOnly) continue; + if (p.Name.Contains(".")) continue; + designItemProperties.Add(item.Properties[p.Name]); + } + designItemProperties.AddRange(item.Properties); + + foreach (DesignItemProperty p in Linq.Distinct(designItemProperties)) { + properties.Add(new DesignItemDataProperty(this, p)); + } + } + + /// + /// 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. + /// + public static IPropertyEditorDataSource GetDataSourceForDesignItem(DesignItem item) + { + return item.GetBehavior() ?? new DesignItemDataSource(item); + } + + + /// See + public string Name { + get { return item.Name ?? ""; } + set { item.Name = value; } + } + + /// + /// Is raised when the name of the design item changes. + /// + public event EventHandler NameChanged { + add { item.NameChanged += value; } + remove { item.NameChanged -= value; } + } + + /// See + public string Type { + get { + return item.Component.GetType().Name; + } + } + + /// See + public ImageSource Icon { + get { return null; } + } + + /// See + public ICollection Properties { + get { return properties; } + } + + /// See + public bool CanAddAttachedProperties { + get { + return item.Component is DependencyObject; + } + } + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/IPropertyEditorDataSource.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/IPropertyEditorDataSource.cs new file mode 100644 index 0000000000..240e316fc9 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/IPropertyEditorDataSource.cs @@ -0,0 +1,92 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Windows.Media; +namespace ICSharpCode.WpfDesign.PropertyEditor +{ + /// + /// Interface for data sources used by the property editor to display the list of properties. + /// + public interface IPropertyEditorDataSource + { + /// + /// Gets/Sets the name of the item. Returns null when the item does not support having a name. + /// + string Name { get; set; } + + /// + /// Gets the type of the item (for display only). + /// + string Type { get; } + + /// + /// Gets the icon of the item (for display only) + /// + ImageSource Icon { get; } + + /// + /// Gets the collection of properties. + /// + ICollection Properties { get; } + + /// + /// Gets if adding attached properties is supported. + /// + bool CanAddAttachedProperties { get; } + } + + /// + /// Represents a property inside a . + /// + public interface IPropertyEditorDataProperty + { + /// + /// Gets the data source that own this property. + /// + IPropertyEditorDataSource OwnerDataSource { get; } + + /// + /// Gets the category this property uses. + /// + string Category { get; } + + /// + /// Gets the name of the property. + /// + string Name { get; } + + /// + /// Gets the description of the property. + /// + string Description { get; } + + /// + /// 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. + /// + bool IsSet { get; set; } + + /// + /// Gets/Sets the value of the property. + /// + object Value { get; set; } + + /// + /// Gets if using a custom expression is supported. + /// + bool CanUseCustomExpression { get; } + + /// + /// Sets a custom expression. + /// + void SetCustomExpression(string expression); + } +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultiSelectionDataSource.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultiSelectionDataSource.cs new file mode 100644 index 0000000000..9ab06ee567 --- /dev/null +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/PropertyEditor/MultiSelectionDataSource.cs @@ -0,0 +1,33 @@ +// +// +// +// +// $Revision$ +// + +using System; +using System.Collections.Generic; + +namespace ICSharpCode.WpfDesign.PropertyEditor +{ + /* + /// + /// Implements IPropertyEditorDataSource by combining the information from multiple data sources. + /// + public class MultiSelectionDataSource : IPropertyEditorDataSource + { + readonly IPropertyEditorDataSource[] data; + + /// + /// Creates a new MultiSelectionDataSource instance. + /// + public MultiSelectionDataSource(ICollection sources) + { + if (sources == null) + throw new ArgumentNullException("sources"); + data = Linq.ToArray(sources); + } + + } + */ +} diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ServiceContainer.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ServiceContainer.cs index 082b3bf4f5..715f64a8be 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ServiceContainer.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/ServiceContainer.cs @@ -7,7 +7,6 @@ using System; using System.Collections.Generic; -using System.ComponentModel; namespace ICSharpCode.WpfDesign { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs index a44c5423f5..c6f916327f 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/Services.cs @@ -8,7 +8,6 @@ using System; using System.Collections.Generic; using System.Windows; -using System.Windows.Media; namespace ICSharpCode.WpfDesign { diff --git a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj index c79b466756..352b057e1c 100644 --- a/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj +++ b/src/AddIns/DisplayBindings/WpfDesign/WpfDesign/Project/WpfDesign.csproj @@ -79,6 +79,10 @@ + + + + @@ -88,5 +92,6 @@ + \ No newline at end of file