This project is read-only.

See C# Demo App Screenshots here: Demo App Screenshots, also see Hello World
This library isn't limited to C#. See an IronPython example here: Iron Python Example and an F# example here: F Sharp Example
Remaining To-Do Items: To-Do List
Tutorials and Details: Dictionaries, Easy as 1-2-3-4-5, Selectors, Events, How-To Examples, Generators (Prototypes), Memory Profile, Sorting, Group Descriptions, Context Menu Example, Cascading ListBox, Visual State Manager
Architectural Discussion: Model-View-Presenter

UPDATES - this page is more of a history of all the updates from the beginning of WPF-CPS to current

Recently Completed Functionality
1. add Generators 2.0: canned complex solutions . . . e.g. cascading listboxes "generated all at once". This type of thing is something regular WPF couldn't let you build up to since it always meant more XAML (which is less easy to share in just a .dll for other programmers)DONE 6/23/2013 I didn't tie in Generators at all, but merely gave an example of a Cascading ListBox. Good enough.
2. create canned canvas-based dialogs; for example, yes-no-cancel, combo editor dialog, radio button dialog, etc.DONE 6/22/2013 - Created Contemporary Style for OK Dialog. Would be nice to loop back to complete Yes-No-Cancel Dialog, Combo Editor Dialog, etc. but for now, the OK Dialog at least points the way . . .
1. Maybe add a WeakReferenceDictionary to Application.Current dictionary or helper/wrapper methods for the DemoApp allowing adding, retrieving, and deleting Actions to Application.Current by guid key-x-y? . . . Allowing disposing from Application.Current dictionary by key as well?DONE 6/22/2013 - Added GlobalStoreService to DemoApp. No WeakReferenceDictionary, just helpers to store and clear references by Tab Control, e.g. clear all global items that were stored for Tab Item 3. Also, cleaned up TabControlService.
1. Provide example of achieving ContextMenu via Canvas (similar to Modal Dialog)DONE 6/13/2013
15. allow code to enable removing the "chrome" from the TabControl Headers to support TabControls that need to be of a different color, e.g. a dark theme, like midnight. Maybe fix DataGrid selectors "chrome" too?DONE 6/10/2013
Maybe add a ModifyAtXY to be used on inner chain, e.g. after add anything or add existing?--DONE 6/10/2013
4. Provide better "templating" support/convenience methods for the regular WPF ButtonDONE 6/9/2013
8. Enable changing mouseovercolor on ComboBox button-currently it displays the Aero highlight color. DONE 6/9/2013
9. Expander seems to have the same issue, the Aero highlight on the little circle icon on mouseover.DONE 6/6/2013
36. add support for recursing UP instead of just downDONE 6/02/2013
37. add support for Skins via SkinExt, leverage Selectors combined with set of type parameters to ChangeSkin on all elements of those types. Can even pass in Actions to vary how each Type is changed.DONE 6/03/2013
3. Consider putting in support for Group Descriptions in ListBox?DONE 6/02/2013 support Grouping in ListBox and ListView. Also, added support for equivalent of swapping in CustomViews into ListView.View.
4. Make Canvas an IComposite? In other words, a CanvasComposite?DONE 4/20/2013
33. Re-visit and improve the IronPython Demo.DONE 4/19/2013
Maybe add support to menu for borderbrush, borderthickness, padding, and icon? DONE 4/17/2013 - added support for adding images to menuitems, and cleaned up the border color support. Also, cleaned up issues with implied/default padding based on the internal Grid in the Menu's control template.
More Selector support - e.g. bool parameter to only return Parents or support for calling DisposeEvents down a chainDONE 2/03/2013
Address Caveat by either removing extra stackpanels OR adding support for headers/footers on Composites?DONE 3/15/2013 - headers and footers can likely be achieved thru normal means of wrapping an element inside a new panel.
Add Generators - these are just helper methods to generate and add potentially multiple children or even multiple Composites all at once; for instance, I could envision a helper to add multiple labels or label-textbox pairs?DONE - added 3/29/2013
Maybe add SetClass, RetrieveByClass?DONE - added 3/29/2013

1/21/2013-I started working on the Selectors engine, e.g. Select All FrameworkElements By Type.
1/10/2013-working on improving TreeView support this week . . . Also, I now freeze the bitmap images to prevent memory leaks . . .
1/5/2013-improved support for ComboBox. Added type-ahead (via TextSearch.Text.)
12-27-2012-IComposite is completed (but not tested fully yet.) New container types are available.
12-28-2012-Performed quite a comprehensive cleanup. The demo now uses BeginSettings...EndSettings and BeginComposite...EndComposite 100%. It appears solid. I could use help testing/pounding away at it?
12-29-2012-Added a new version of BeginComposite method that takes zero parameters. It merely generates its own Guid key internally for those cases where maintaining a handle to the Guid isn't important. Also, added AdornerDecorator extensions with a Validate Fields example, adorning Text Boxes with red rectangles if required fields are null/empty. Added helper DisplayErrorRectangle and RemoveErrorRectangle methods. Added support for ToolBarTray, ToolBar, and Expander.
UPDATE 3/15/2013: I finally streamlined the structure of the Composite to just Border-ContentControl-Container-Children. Also, I added a new IComposite container type called ContentControlComposite.
UPDATE: 3/18/2013: I revamped the Demo App to now use ten separate User Controls tied to ten separate Tab Items.
UPDATE: 3/20/2013: I am in the process of adding functionality similar to CSS Classes to allow easy "global" changing of settings. UI Elements are stamped with a selector class name and then may be retrieved by this class name later using the regular Selectors engine. I am adjusting it to allow adding up to three classes per UI Element, e.g. red box tab3.
UPDATE: 3/25/2013: I just checked-in the first draft of Generators which will allow you to generate and add multiple Composites (each with a Child) at a time to a subset of supported parents (Grid, StackPanel, WrapPanel, DockPanel, or GroupBox) based on a Prototype (of the Child) passed-in and a defined range.
An Action "constructor" is also passed-in to allow you to vary the construction of a particular generated Composite's Child. This also allows you to delay Initialization and Settings until after the Child has been created and cloned by putting these in this Action Constructor, which is important for technical reasons.
UPDATE: 3/28/2013: I cleaned up the re-sizing example (Tab Item 3) for when you want to remove/re-add a user control to a region with it re-sizing properly if you re-size the window. I also used this same Tab Item 3 to add a new example of closing/re-adding an entire Tab. To support this, I added an X next to the title text of each Tab. Tab Item 3 is working; I just need to extend out this support to the other tabs as well.

Always call Initialize on Parents after instantiating them. Always add via Begin Composite...End Composite. Settings may be added via BeginSettings...EndSettings OR by getting a handle to the child after it has been added and updating it directly. Also, always use the Subscribe Event methods that are provided. Basically, this assures that you are hooking into the WPF Composites infrastructure and allows unsubscribing events via method calls or a Dispose method (leveraging Rx IDisposables.)

In terms of order, always add Settings and EventSubscriptions first, then call BeginComposite to add composites (so that they may pick up the settings and subscriptions!)

UPDATE - December 17th, 2012 - added new SetAttachedProperty overload to allow setting by row-column (aka x-y coordinates):
//Use SetAttachedProperty with overload which allows specifying row-column
              .SetAttachedProperty<Label, Grid>(
              "ColumnSpan", 0, 0, obj => { obj.SetValue(Grid.ColumnSpanProperty, 2); })

UPDATE - December 2nd, 2012 - added new Fluent Interface syntax for Settings as well:
            //Default Settings
                .SetFont<DockPanel>(1, 0, "Arial", 11, FontWeights.DemiBold, FontStyles.Italic)
                .Set<Rectangle, DockPanel>("Fill", Brushes.DarkGreen)
                .Set<Rectangle, DockPanel>("Stroke", Brushes.Black)
                .Set<Rectangle, DockPanel>("StrokeThickness", 3.00D)
                .SetItemBorderSettings(double.NaN, double.NaN, Brushes.Gold, new Thickness(2))

UPDATE - November 30th, 2012 - added new Fluent Interface syntax. Instead of AddComposite, it is now BeginComposite . . . EndComposite:

                .AddAnything<Rectangle, DockPanel>(0, 0)
                .AddText(1, 0, "Click to remove.")
                .AddText(2, 0, "This is text at Row 2 Column 0")
                .EndComposite(new DockArgs(Dock.Right))
                "PreviewMouseLeftButtonDown", new MouseButtonEventHandler(my_MouseSingleClick));

UPDATE - the following FIVE new generic methods offer great flexibility:
.Set<Rectangle, DockPanel>("Fill", Brushes.DarkGreen) 
.Set<Rectangle, DockPanel>(0, 0, "Fill", Brushes.Red) //overload for x-y coordinates
.SetAttachedProperty<Rectangle, DockPanel>("Background", obj => { obj.SetValue(Rectangle.FillProperty, Brushes.LightSeaGreen); })
.AddExisting<Button, Grid>(gridguid1, 4, 1, myButton)
.AddAnything<TextBox, Grid>(gridguid1, 2, 1)
- also added support for SubscribeAnyEventOnParent, SubscribeAnyEvent (at Guid-X-Y coordinates), SubscribeAnyEventOnContainer, and SubscribeAnyEventOnBorder for flexibility subscribing to events at X and Y, etc. (NOTE: I have subsequently renamed these!):
.AddAnything<TextBox, Grid>(gridguid1, 2, 1).SubscribeAnyEvent<TextBox, Grid>(gridguid1, 2, 1, "TextChanged", new TextChangedEventHandler( (sender, e) => { MessageBox.Show("Text Changed Added Length: " + e.Changes.ToList().FirstOrDefault().AddedLength.ToString()); }  ))

.SubscribeAnyEventOnContainer<Grid>(gridguid1, "GotFocus", new RoutedEventHandler(                     (sender, e) => { MessageBox.Show("GotFocus " + e.Source.ToString()); }))
myGrid.AddAtCoordinates<Grid, GridArgs>(gridguid1, new GridArgs(0, 0), container =>
            { . . . .  })
            .SubscribeAnyEventOnBorder<Grid>(gridguid1, "MouseEnter",
            new MouseEventHandler((sender, e) =>
                MessageBox.Show("MouseEnter X-position: " + e.GetPosition((IInputElement)sender).X.ToString());

trv.Apply(settings =>
                settings.SubscribeAnyEventOnParent<TreeView>("SelectedItemChanged", new RoutedPropertyChangedEventHandler<object>( 
                     (sender, e)=>{ MessageBox.Show("Selected Item Changed "+e.Source.ToString()); } ))

NOTE: for TextBlocks, I add text as a Run set on the Inlines collection. If you manually get a textblock and get the Text property, it will likely be empty. I added extension methods GetText() and SetText() on the TextBlock class itself to help out with this. These two methods get a handle to the first Inline. The reason I used inline instead of Text is because I want to eventually, possibly add support for different formatting within Text via multiple Inlines. So for now, it just serves as a reminder to me of this.

Also, note that I haven't yet added support to the ListBox for disabled colors.

Original Updates

OTHER NOTES ON THE FUTURE: I imagine that it might be a good idea to add support for FlowDocumentScrollViewer for the ListBox for wrapping Text around an image. However, this may prove problematic since it inherits from FrameworkContentElement instead of FrameworkElement, I believe. Most of the generic methods expect T to be FrameworkElement.

Last edited Jan 26, 2014 at 6:57 AM by stagathome0069, version 124


No comments yet.