- Olbert_Utilities.zip
- Olbert.Utilities
- CryptorLib
- documentation
- bin
- Content Layout.content
- Creative Commons Attribution Share Alike.aml
- Cryptor Overview.aml
- GLPL.aml
- GPL.aml
- Licenses.aml
- Miscellaneous Utilities Overview.aml
- nHydrate Installer Overview.aml
- nHydrate Utilities.aml
- Olbert.Utils.shfbproj
- Open Source License v3.aml
- overview.aml
- Release Notes.aml
- Wizard Framework.aml
- WPF Utilities.aml
- MiscUtilities
- MiscUtilitiesCore
- nHydrateInstaller
- nHydrateUtils
- NotMine
- NotMineWPF
- OlbertUtilities.sln
- OlbertUtilities.suo
- WPFUtilities
- WPFWizard
|
/*
* Olbert.Utilities.WPF
* utilities for simplifying the use of nHydrate entities in WPF applications
* Copyright (C) 2011 Mark A. Olbert
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Collections.ObjectModel;
using System.Windows.Controls;
using System.Windows;
namespace Olbert.Utilities.WPF
{
/// <summary>
/// Defines a class, dervied from ObservableCollection<ResourceBinder>, which defines all of
/// the various property bindings for a particular WizardPage and various properties of a WizardPage
/// </summary>
public class PageBinder : ObservableCollection<ResourceBinder>
{
private WizardWindow wizard;
private Type pageType;
private ConstructorInfo pageCtor;
private Uri pageUri;
/// <summary>
/// Creates a new instance
/// </summary>
public PageBinder()
{
}
/// <summary>
/// Creates a new instance which is a copy of the supplied instance
/// </summary>
/// <param name="toCopy">the instance to duplicate</param>
protected PageBinder( PageBinder toCopy )
{
wizard = toCopy.wizard;
pageType = toCopy.pageType;
pageCtor = toCopy.pageCtor;
Title = toCopy.Title;
pageUri = toCopy.pageUri;
foreach( ResourceBinder propBinder in toCopy )
{
Add(propBinder.Copy());
}
SourcePath = toCopy.SourcePath;
Validator = toCopy.Validator;
StateValuesProcessor = toCopy.StateValuesProcessor;
PageValuesProcessor = toCopy.PageValuesProcessor;
}
/// <summary>
/// Returns a new object which is a copy of the current instance
/// </summary>
/// <returns>a new object which is a copy of the current instance</returns>
public virtual PageBinder Copy()
{
return new PageBinder(this);
}
/// <summary>
/// Gets or sets the WizardWindow that is hosting the binding collection
/// </summary>
public WizardWindow Wizard
{
get { return wizard; }
set
{
wizard = value;
foreach( ResourceBinder resBinder in this )
{
resBinder.Wizard = wizard;
}
}
}
/// <summary>
/// Gets or sets the title for the WizardPage
/// </summary>
public string Title { get; set; }
/// <summary>
/// Gets or sets the path to the XAML file defining the WizardPage being described by this
/// instance. This is defined based on the "project-relative" path within the Visual Studio
/// solution explorer window.
/// </summary>
public string SourcePath { get; set; }
/// <summary>
/// Creates a new instance of the WizardPage described by this instance
/// </summary>
/// <returns></returns>
public WizardPage CreatePage()
{
if( pageCtor == null ) return null;
return (WizardPage) pageCtor.Invoke(null);
}
/// <summary>
/// Gets or sets the Uri for locating the compiled XAML file defining the WizardPage described
/// by this instance
/// </summary>
public Uri PageUri
{
get
{
if( PageType == null ) return null;
if( pageUri == null )
{
// the xaml is assumed to be in the same assembly that defines the WizardPage class
Assembly pageAss = Assembly.GetAssembly(PageType);
string[] nameParts = pageAss.FullName.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
pageUri = new Uri(String.Format("/{0};component/{1}", nameParts[0], SourcePath), UriKind.RelativeOrAbsolute);
}
return pageUri;
}
}
#region Page side of binding
/// <summary>
/// Gets or sets the Type of the WizardPage being described by this instance
/// </summary>
public Type PageType
{
get { return pageType; }
set
{
pageType = value;
if( pageType == null ) pageCtor = null;
else pageCtor = pageType.GetConstructor(Type.EmptyTypes);
foreach( ResourceBinder wizBinder in this )
{
wizBinder.PageType = pageType;
}
}
}
/// <summary>
/// Gets the currently displayed WizardPage, which may or may not be of the same Type as
/// the WizardPage described by this instance
/// </summary>
protected WizardPage CurrentPage
{
get
{
if( wizard == null ) return null;
if( wizard.PageFrame == null ) return null;
return wizard.PageFrame.Content as WizardPage;
}
}
/// <summary>
/// Gets or sets the processor class used to modify property values retrieved from the
/// WizardPage object before they are used to set property values on the state object
/// </summary>
public PageValuesProcessor PageValuesProcessor { get; set; }
/// <summary>
/// Retrieves and modifies the property values of bound WizardPage properties
/// </summary>
/// <returns>a collection of bound WizardPage property values</returns>
public PropertyBindingValues GetPageValues()
{
if( PageType == null ) return null;
if( Wizard == null ) return null;
if( CurrentPage == null ) return null;
if( !CurrentPage.GetType().IsOrIsDerivedFrom(PageType) )
return null;
PropertyBindingValues propValues = new PropertyBindingValues(Wizard);
foreach( ResourceBinder curBinding in this )
{
PageBindingResult result = curBinding.GetPageValue();
PageBindingValue value = result as PageBindingValue;
propValues.Add(new PropertyBindingValue(curBinding, ( value == null ) ? null : value.Value, result.IsValid));
}
PageValuesProcessor processor = ( PageValuesProcessor == null ) ? new PageValuesProcessor() : PageValuesProcessor;
return processor.ModifyPageValues(propValues, State, Wizard);
}
/// <summary>
/// Gets or sets a custom validator to be used with the WizardPage being described by this
/// instance
/// </summary>
public WizardPageValidator Validator { get; set; }
/// <summary>
/// Validates a collection of WizardPage bound property values
/// </summary>
/// <param name="values">the WizrdPage bound property values to be validated</param>
/// <returns>a ValidationResult describing the results of the validation process</returns>
public PageBindingResult ValidatePageValues( PropertyBindingValues values )
{
if( Validator == null ) return new PageBindingValue();
if( values == null )
return PageBindingOutcome.UndefinedObject.ToError("the supplied PropertyBindingValues object is undefined");
if( State == null )
return PageBindingOutcome.UndefinedObject.ToError("the wizard state object was undefined");
if( StateType == null )
return PageBindingOutcome.UndefinedObject.ToError("StateType is undefined");
if( Wizard == null )
return PageBindingOutcome.UndefinedObject.ToError("the WizardWindow object was undefined");
return Validator.Validate(values, State, Wizard);
}
#endregion
#region State side of binding
/// <summary>
/// Gets the Type of the primary state object. Returns null if the Wizard property is not set
/// or if the WizardWindow's WizardState property is undefined
/// for the
/// </summary>
public Type StateType
{
get
{
if( wizard == null ) return null;
if( wizard.WizardState == null ) return null;
return wizard.WizardState.GetType();
}
}
/// <summary>
/// Gets the object holding the wizard's state. Returns null if the Wizard property is not set.
/// </summary>
protected object State
{
get
{
if( wizard == null ) return null;
return wizard.WizardState;
}
}
/// <summary>
/// Gets or sets the processor class used to modify property values retrieved from the
/// state object before they are used to set property values on the WizardPage object
/// </summary>
public StateValuesProcessor StateValuesProcessor { get; set; }
/// <summary>
/// Retrieves and modifies the property values of bound state properties
/// </summary>
/// <returns>a collection of bound state property values</returns>
public PropertyBindingValues GetStateValues()
{
if( wizard == null ) return null;
if( StateType == null ) return null;
if( State == null ) return null;
// get the raw values from the state object
PropertyBindingValues propValues = new PropertyBindingValues(Wizard);
foreach( ResourceBinder curBinding in this )
{
PageBindingResult result = curBinding.GetStateValue();
PageBindingValue value = result as PageBindingValue;
propValues.Add(new PropertyBindingValue(curBinding, ( value == null ) ? null : value.Value, result.IsValid));
}
// use the default preprocessor if one wasn't defined
StateValuesProcessor preprocessor = ( StateValuesProcessor == null ) ? new StateValuesProcessor() : StateValuesProcessor;
return preprocessor.ModifyStateValues(propValues, State, Wizard);
}
#endregion
/// <summary>
/// Overrides the base implementation to set the PageType and StateType, if one is defined,
/// properties of objects being added to the collection
/// </summary>
/// <param name="index">the index location within the collection where the item is being added</param>
/// <param name="item">the ResourceBinder object being inserted</param>
protected override void InsertItem( int index, ResourceBinder item )
{
item.PageType = PageType;
item.Wizard = Wizard;
base.InsertItem(index, item);
}
/// <summary>
/// Overrides the base implementation to set the PageType and StateType, if one is defined,
/// properties of objects being set into the collection
/// </summary>
/// <param name="index">the index location within the collection where the item is being set</param>
/// <param name="item">the ResourceBinder object being set</param>
protected override void SetItem( int index, ResourceBinder item )
{
item.PageType = PageType;
item.Wizard = Wizard;
base.SetItem(index, item);
}
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
Some people like to do crossword puzzles to hone their problem-solving skills. Me, I like to write software for the same reason.
A few years back I passed my 50th anniversary of programming. I believe that means it's officially more than a hobby or pastime. In fact, it may qualify as an addiction
.
I mostly work in C# and Windows. But I also play around with Linux (mostly Debian on Raspberry Pis) and Python.