Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / System / Windows / TriggerBase.cs / 1 / TriggerBase.cs
using System.Collections.Specialized;
using System.IO;
using System.Windows.Markup;
using System.Security.Permissions;
using MS.Utility;
using MS.Internal;
using System;
using System.ComponentModel; // DesignerSerializationVisibilityAttribute & DefaultValue
using System.Diagnostics;
namespace System.Windows
{
///
/// A visual trigger is the base class for specifying a conditional
/// value within a Style object.
///
///
/// The TriggerBase class deals with the values, and a derived class
/// is responsible for handling the conditions that determine whether a
/// value is to be used.
///
/// In other words, the TriggerBase class stores the "then" portion
/// of an if/then. The derived class handles the "if" part.
///
/// The most common derived type is the Trigger class. A
/// property trigger is conditional on property values, creating logic like:
///
/// if( MouseOver == true ) then (Background = Red )
///
/// The various Set methods in this class handles the (Background = Red) portion
/// of this logic.
///
[Localizability(LocalizationCategory.None, Readability=Readability.Unreadable)]
public abstract class TriggerBase : DependencyObject
{
internal TriggerBase()
{
;
}
///
/// A collection of trigger actions to perform when this trigger
/// object becomes active.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TriggerActionCollection EnterActions
{
get
{
// Verify Context Access
VerifyAccess();
if( _enterActions == null )
{
_enterActions = new TriggerActionCollection();
if( IsSealed )
{
// This collection might receive its first query after
// the containing trigger had already been sealed
_enterActions.Seal(this);
}
}
return _enterActions;
}
}
// Internal way to check without triggering a pointless allocation
internal bool HasEnterActions { get { return _enterActions != null && _enterActions.Count > 0; } }
///
/// A collection of trigger actions to perform when this trigger
/// object becomes inactive.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TriggerActionCollection ExitActions
{
get
{
// Verify Context Access
VerifyAccess();
if( _exitActions == null )
{
_exitActions = new TriggerActionCollection();
if( IsSealed )
{
// This collection might receive its first query after
// the containing trigger had already been sealed
_exitActions.Seal(this);
}
}
return _exitActions;
}
}
// Internal way to check without triggering a pointless allocation
internal bool HasExitActions { get { return _exitActions != null && _exitActions.Count > 0; } }
// Here's the internal version that does what Robby thinks it should do.
internal bool ExecuteEnterActionsOnApply
{
get
{
return true;
}
}
internal bool ExecuteExitActionsOnApply
{
get
{
return false;
}
}
/* Here's the version that looks like a public API. (Needs Style/Template parser changes before these will actually parse.)
// These fields determine what we do about any existing Enter/ExitActions
// when the Trigger is first applied.
///
/// If set to 'true', EnterActions will be executed immediately if the
/// conditions are met, before any "enter" change has occurred.
///
// This is on the assumption that the "enter" change has occurred already.
// For example: the IsChecked property
// change occurred before the CheckBox Style/Template is applied.
[DefaultValue(false)]
public bool ExecuteEnterActionsOnApply
{
get
{
return _executeEnterActionsOnApply;
}
set
{
if (IsSealed)
{
throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "trigger"));
}
_executeEnterActionsOnApply = value;
}
}
///
/// If set to 'true', ExitActions will be executed immediately if the
/// conditions are not met, before any "exit" change has occurred.
///
[DefaultValue(false)]
public bool ExecuteExitActionsOnApply
{
get
{
return _executeExitActionsOnApply;
}
set
{
if (IsSealed)
{
throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "trigger"));
}
_executeExitActionsOnApply = value;
}
}
*/
///
/// Parameter validation work common to the SetXXXX methods that deal
/// with the container node of the Style/Template.
///
internal void ProcessParametersContainer(DependencyProperty dp)
{
// Not allowed to use Style to affect the StyleProperty.
if (dp == FrameworkElement.StyleProperty)
{
throw new ArgumentException(SR.Get(SRID.StylePropertyInStyleNotAllowed));
}
}
///
/// Parameter validation work common to the SetXXXX methods that deal
/// with visual tree child nodes.
///
internal string ProcessParametersVisualTreeChild(DependencyProperty dp, string target)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (target.Length == 0)
{
throw new ArgumentException(SR.Get(SRID.ChildNameMustBeNonEmpty));
}
return String.Intern(target);
}
///
/// After the parameters have been validated, store it in the
/// PropertyValues collection.
///
///
/// All these will be looked at again (and processed into runtime
/// data structures) by Style.Seal(). We keep them around even after
/// that point should we need to serialize this data back out.
///
internal void AddToPropertyValues(string childName, DependencyProperty dp, object value, PropertyValueType valueType)
{
// Store original data
PropertyValue propertyValue = new PropertyValue();
propertyValue.ValueType = valueType;
propertyValue.Conditions = null; // Delayed - derived class is responsible for this item.
propertyValue.ChildName = childName;
propertyValue.Property = dp;
propertyValue.ValueInternal = value;
PropertyValues.Add(propertyValue);
}
//CASRemoval:[StrongNameIdentityPermission(SecurityAction.InheritanceDemand, PublicKey = Microsoft.Internal.BuildInfo.WCP_PUBLIC_KEY_STRING)]
internal override void Seal()
{
// Verify Context Access
VerifyAccess();
base.Seal();
// Super classes have added all delayed conditions
// Track Dependent/Source relationship for prediction
for (int i = 0; i < PropertyValues.Count; i++)
{
PropertyValue propertyValue = PropertyValues[i];
DependencyProperty dependent = propertyValue.Property;
for (int j = 0; j < propertyValue.Conditions.Length; j++)
{
DependencyProperty source = propertyValue.Conditions[j].Property;
// Check for obvious cycles. Don't test for cycles if we have
// something other than self as the target, since this means that
// the templatedParent is presumably not the target. See windows bug
// 984916 for details.
if (source == dependent && propertyValue.ChildName == StyleHelper.SelfName)
{
throw new InvalidOperationException(SR.Get(SRID.PropertyTriggerCycleDetected, source.Name));
}
}
}
if( _enterActions != null )
{
_enterActions.Seal(this);
}
if( _exitActions != null )
{
_exitActions.Seal(this);
}
// Remove thread affinity so it can be accessed across threads
DetachFromDispatcher();
}
// This will transfer information in the _setters collection to PropertyValues array.
internal void ProcessSettersCollection(SetterBaseCollection setters)
{
// Add information in Setters collection to PropertyValues array.
if( setters != null )
{
// Seal Setters
setters.Seal();
for (int i = 0; i < setters.Count; i++ )
{
Setter setter = setters[i] as Setter;
if( setter != null )
{
DependencyProperty dp = setter.Property;
object value = setter.ValueInternal;
string target = setter.TargetName;
if( target == null )
{
ProcessParametersContainer(dp);
target = StyleHelper.SelfName;
}
else
{
target = ProcessParametersVisualTreeChild(dp, target); // name string will get interned
}
DynamicResourceExtension dynamicResource = value as DynamicResourceExtension;
if (dynamicResource == null)
{
AddToPropertyValues(target, dp, value, PropertyValueType.Trigger);
}
else
{
AddToPropertyValues(target, dp, dynamicResource.ResourceKey, PropertyValueType.PropertyTriggerResource);
}
}
else
{
throw new InvalidOperationException(SR.Get(SRID.VisualTriggerSettersIncludeUnsupportedSetterType, setter.GetType().Name));
}
}
}
}
// Define the DO's inheritance context
internal override DependencyObject InheritanceContext
{
get { return _inheritanceContext; }
}
// Receive a new inheritance context (this will be a FE/FCE)
internal override void AddInheritanceContext(DependencyObject context, DependencyProperty property)
{
InheritanceContextHelper.AddInheritanceContext(context,
this,
ref _hasMultipleInheritanceContexts,
ref _inheritanceContext);
}
// Remove an inheritance context (this will be a FE/FCE)
internal override void RemoveInheritanceContext(DependencyObject context, DependencyProperty property)
{
InheritanceContextHelper.RemoveInheritanceContext(context,
this,
ref _hasMultipleInheritanceContexts,
ref _inheritanceContext);
}
// Says if the current instance has multiple InheritanceContexts
internal override bool HasMultipleInheritanceContexts
{
get { return _hasMultipleInheritanceContexts; }
}
// This ranking is used when trigger needs to be sorted relative to
// the ordering, as when determining precedence for enter/exit
// animation composition. Otherwise, it stays at default value of zero.
internal Int64 Layer
{
get { return _globalLayerRank; }
}
// Set self rank to current number, increment global static.
internal void EstablishLayer()
{
if( _globalLayerRank == 0 )
{
lock(Synchronized)
{
_globalLayerRank = _nextGlobalLayerRank++;
}
if( _nextGlobalLayerRank == Int64.MaxValue )
{
throw new InvalidOperationException(SR.Get(SRID.PropertyTriggerLayerLimitExceeded));
}
}
}
// evaluate the current state of the trigger
internal virtual bool GetCurrentState(DependencyObject container, UncommonField dataField)
{
Debug.Assert( false,
"This method was written to handle Trigger, MultiTrigger, DataTrigger, and MultiDataTrigger. It looks like a new trigger type was added - please add support as appropriate.");
return false;
}
// Collection of TriggerConditions
internal TriggerCondition[] TriggerConditions
{
get { return _triggerConditions; }
set { _triggerConditions = value; }
}
// Synchronized (write locks, lock-free reads): Covered by the TriggerBase instance
/* property */ internal FrugalStructList PropertyValues = new FrugalStructList();
// Global, cross-object synchronization
private static object Synchronized = new object();
// Conditions
TriggerCondition[] _triggerConditions;
// Fields to implement DO's inheritance context
private DependencyObject _inheritanceContext = null;
private bool _hasMultipleInheritanceContexts = false;
// Fields to handle enter/exit actions.
private TriggerActionCollection _enterActions = null;
private TriggerActionCollection _exitActions = null;
// On hold - is this a new public API we want to do?
// private bool _executeEnterActionsOnApply = false;
// private bool _executeExitActionsOnApply = false;
private Int64 _globalLayerRank = 0;
private static Int64 _nextGlobalLayerRank = System.Windows.Media.Animation.Storyboard.Layers.PropertyTriggerStartLayer;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System.Collections.Specialized;
using System.IO;
using System.Windows.Markup;
using System.Security.Permissions;
using MS.Utility;
using MS.Internal;
using System;
using System.ComponentModel; // DesignerSerializationVisibilityAttribute & DefaultValue
using System.Diagnostics;
namespace System.Windows
{
///
/// A visual trigger is the base class for specifying a conditional
/// value within a Style object.
///
///
/// The TriggerBase class deals with the values, and a derived class
/// is responsible for handling the conditions that determine whether a
/// value is to be used.
///
/// In other words, the TriggerBase class stores the "then" portion
/// of an if/then. The derived class handles the "if" part.
///
/// The most common derived type is the Trigger class. A
/// property trigger is conditional on property values, creating logic like:
///
/// if( MouseOver == true ) then (Background = Red )
///
/// The various Set methods in this class handles the (Background = Red) portion
/// of this logic.
///
[Localizability(LocalizationCategory.None, Readability=Readability.Unreadable)]
public abstract class TriggerBase : DependencyObject
{
internal TriggerBase()
{
;
}
///
/// A collection of trigger actions to perform when this trigger
/// object becomes active.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TriggerActionCollection EnterActions
{
get
{
// Verify Context Access
VerifyAccess();
if( _enterActions == null )
{
_enterActions = new TriggerActionCollection();
if( IsSealed )
{
// This collection might receive its first query after
// the containing trigger had already been sealed
_enterActions.Seal(this);
}
}
return _enterActions;
}
}
// Internal way to check without triggering a pointless allocation
internal bool HasEnterActions { get { return _enterActions != null && _enterActions.Count > 0; } }
///
/// A collection of trigger actions to perform when this trigger
/// object becomes inactive.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public TriggerActionCollection ExitActions
{
get
{
// Verify Context Access
VerifyAccess();
if( _exitActions == null )
{
_exitActions = new TriggerActionCollection();
if( IsSealed )
{
// This collection might receive its first query after
// the containing trigger had already been sealed
_exitActions.Seal(this);
}
}
return _exitActions;
}
}
// Internal way to check without triggering a pointless allocation
internal bool HasExitActions { get { return _exitActions != null && _exitActions.Count > 0; } }
// Here's the internal version that does what Robby thinks it should do.
internal bool ExecuteEnterActionsOnApply
{
get
{
return true;
}
}
internal bool ExecuteExitActionsOnApply
{
get
{
return false;
}
}
/* Here's the version that looks like a public API. (Needs Style/Template parser changes before these will actually parse.)
// These fields determine what we do about any existing Enter/ExitActions
// when the Trigger is first applied.
///
/// If set to 'true', EnterActions will be executed immediately if the
/// conditions are met, before any "enter" change has occurred.
///
// This is on the assumption that the "enter" change has occurred already.
// For example: the IsChecked property
// change occurred before the CheckBox Style/Template is applied.
[DefaultValue(false)]
public bool ExecuteEnterActionsOnApply
{
get
{
return _executeEnterActionsOnApply;
}
set
{
if (IsSealed)
{
throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "trigger"));
}
_executeEnterActionsOnApply = value;
}
}
///
/// If set to 'true', ExitActions will be executed immediately if the
/// conditions are not met, before any "exit" change has occurred.
///
[DefaultValue(false)]
public bool ExecuteExitActionsOnApply
{
get
{
return _executeExitActionsOnApply;
}
set
{
if (IsSealed)
{
throw new InvalidOperationException(SR.Get(SRID.CannotChangeAfterSealed, "trigger"));
}
_executeExitActionsOnApply = value;
}
}
*/
///
/// Parameter validation work common to the SetXXXX methods that deal
/// with the container node of the Style/Template.
///
internal void ProcessParametersContainer(DependencyProperty dp)
{
// Not allowed to use Style to affect the StyleProperty.
if (dp == FrameworkElement.StyleProperty)
{
throw new ArgumentException(SR.Get(SRID.StylePropertyInStyleNotAllowed));
}
}
///
/// Parameter validation work common to the SetXXXX methods that deal
/// with visual tree child nodes.
///
internal string ProcessParametersVisualTreeChild(DependencyProperty dp, string target)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (target.Length == 0)
{
throw new ArgumentException(SR.Get(SRID.ChildNameMustBeNonEmpty));
}
return String.Intern(target);
}
///
/// After the parameters have been validated, store it in the
/// PropertyValues collection.
///
///
/// All these will be looked at again (and processed into runtime
/// data structures) by Style.Seal(). We keep them around even after
/// that point should we need to serialize this data back out.
///
internal void AddToPropertyValues(string childName, DependencyProperty dp, object value, PropertyValueType valueType)
{
// Store original data
PropertyValue propertyValue = new PropertyValue();
propertyValue.ValueType = valueType;
propertyValue.Conditions = null; // Delayed - derived class is responsible for this item.
propertyValue.ChildName = childName;
propertyValue.Property = dp;
propertyValue.ValueInternal = value;
PropertyValues.Add(propertyValue);
}
//CASRemoval:[StrongNameIdentityPermission(SecurityAction.InheritanceDemand, PublicKey = Microsoft.Internal.BuildInfo.WCP_PUBLIC_KEY_STRING)]
internal override void Seal()
{
// Verify Context Access
VerifyAccess();
base.Seal();
// Super classes have added all delayed conditions
// Track Dependent/Source relationship for prediction
for (int i = 0; i < PropertyValues.Count; i++)
{
PropertyValue propertyValue = PropertyValues[i];
DependencyProperty dependent = propertyValue.Property;
for (int j = 0; j < propertyValue.Conditions.Length; j++)
{
DependencyProperty source = propertyValue.Conditions[j].Property;
// Check for obvious cycles. Don't test for cycles if we have
// something other than self as the target, since this means that
// the templatedParent is presumably not the target. See windows bug
// 984916 for details.
if (source == dependent && propertyValue.ChildName == StyleHelper.SelfName)
{
throw new InvalidOperationException(SR.Get(SRID.PropertyTriggerCycleDetected, source.Name));
}
}
}
if( _enterActions != null )
{
_enterActions.Seal(this);
}
if( _exitActions != null )
{
_exitActions.Seal(this);
}
// Remove thread affinity so it can be accessed across threads
DetachFromDispatcher();
}
// This will transfer information in the _setters collection to PropertyValues array.
internal void ProcessSettersCollection(SetterBaseCollection setters)
{
// Add information in Setters collection to PropertyValues array.
if( setters != null )
{
// Seal Setters
setters.Seal();
for (int i = 0; i < setters.Count; i++ )
{
Setter setter = setters[i] as Setter;
if( setter != null )
{
DependencyProperty dp = setter.Property;
object value = setter.ValueInternal;
string target = setter.TargetName;
if( target == null )
{
ProcessParametersContainer(dp);
target = StyleHelper.SelfName;
}
else
{
target = ProcessParametersVisualTreeChild(dp, target); // name string will get interned
}
DynamicResourceExtension dynamicResource = value as DynamicResourceExtension;
if (dynamicResource == null)
{
AddToPropertyValues(target, dp, value, PropertyValueType.Trigger);
}
else
{
AddToPropertyValues(target, dp, dynamicResource.ResourceKey, PropertyValueType.PropertyTriggerResource);
}
}
else
{
throw new InvalidOperationException(SR.Get(SRID.VisualTriggerSettersIncludeUnsupportedSetterType, setter.GetType().Name));
}
}
}
}
// Define the DO's inheritance context
internal override DependencyObject InheritanceContext
{
get { return _inheritanceContext; }
}
// Receive a new inheritance context (this will be a FE/FCE)
internal override void AddInheritanceContext(DependencyObject context, DependencyProperty property)
{
InheritanceContextHelper.AddInheritanceContext(context,
this,
ref _hasMultipleInheritanceContexts,
ref _inheritanceContext);
}
// Remove an inheritance context (this will be a FE/FCE)
internal override void RemoveInheritanceContext(DependencyObject context, DependencyProperty property)
{
InheritanceContextHelper.RemoveInheritanceContext(context,
this,
ref _hasMultipleInheritanceContexts,
ref _inheritanceContext);
}
// Says if the current instance has multiple InheritanceContexts
internal override bool HasMultipleInheritanceContexts
{
get { return _hasMultipleInheritanceContexts; }
}
// This ranking is used when trigger needs to be sorted relative to
// the ordering, as when determining precedence for enter/exit
// animation composition. Otherwise, it stays at default value of zero.
internal Int64 Layer
{
get { return _globalLayerRank; }
}
// Set self rank to current number, increment global static.
internal void EstablishLayer()
{
if( _globalLayerRank == 0 )
{
lock(Synchronized)
{
_globalLayerRank = _nextGlobalLayerRank++;
}
if( _nextGlobalLayerRank == Int64.MaxValue )
{
throw new InvalidOperationException(SR.Get(SRID.PropertyTriggerLayerLimitExceeded));
}
}
}
// evaluate the current state of the trigger
internal virtual bool GetCurrentState(DependencyObject container, UncommonField dataField)
{
Debug.Assert( false,
"This method was written to handle Trigger, MultiTrigger, DataTrigger, and MultiDataTrigger. It looks like a new trigger type was added - please add support as appropriate.");
return false;
}
// Collection of TriggerConditions
internal TriggerCondition[] TriggerConditions
{
get { return _triggerConditions; }
set { _triggerConditions = value; }
}
// Synchronized (write locks, lock-free reads): Covered by the TriggerBase instance
/* property */ internal FrugalStructList PropertyValues = new FrugalStructList();
// Global, cross-object synchronization
private static object Synchronized = new object();
// Conditions
TriggerCondition[] _triggerConditions;
// Fields to implement DO's inheritance context
private DependencyObject _inheritanceContext = null;
private bool _hasMultipleInheritanceContexts = false;
// Fields to handle enter/exit actions.
private TriggerActionCollection _enterActions = null;
private TriggerActionCollection _exitActions = null;
// On hold - is this a new public API we want to do?
// private bool _executeEnterActionsOnApply = false;
// private bool _executeExitActionsOnApply = false;
private Int64 _globalLayerRank = 0;
private static Int64 _nextGlobalLayerRank = System.Windows.Media.Animation.Storyboard.Layers.PropertyTriggerStartLayer;
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- JoinElimination.cs
- Rfc2898DeriveBytes.cs
- ClientRuntimeConfig.cs
- HttpCacheParams.cs
- PixelFormatConverter.cs
- HttpInputStream.cs
- XsltSettings.cs
- TemplateInstanceAttribute.cs
- ResourceManager.cs
- Label.cs
- CqlGenerator.cs
- PageSetupDialog.cs
- SoapWriter.cs
- DocumentPageHost.cs
- DeviceContext.cs
- UrlPath.cs
- MarkupCompilePass1.cs
- ListItemCollection.cs
- TransactionFlowProperty.cs
- BackoffTimeoutHelper.cs
- SpeechEvent.cs
- ProgressBar.cs
- _TransmitFileOverlappedAsyncResult.cs
- ProtocolsConfigurationHandler.cs
- SqlStream.cs
- RpcResponse.cs
- AddInAdapter.cs
- PropertyRef.cs
- DLinqTableProvider.cs
- XslNumber.cs
- Enum.cs
- IsolatedStorage.cs
- ExceptionUtil.cs
- WebPartZoneBase.cs
- Cursor.cs
- XmlCharacterData.cs
- ProxyHwnd.cs
- SamlAction.cs
- FragmentQuery.cs
- Facet.cs
- FormsIdentity.cs
- EncodingTable.cs
- NameValueSectionHandler.cs
- GifBitmapEncoder.cs
- WebPartConnection.cs
- SiteMapDataSource.cs
- LateBoundBitmapDecoder.cs
- RectAnimationUsingKeyFrames.cs
- RelOps.cs
- WpfWebRequestHelper.cs
- FontStretchConverter.cs
- StaticSiteMapProvider.cs
- Rotation3DAnimationBase.cs
- TagMapInfo.cs
- CodeTryCatchFinallyStatement.cs
- IriParsingElement.cs
- TextReader.cs
- WebPartEventArgs.cs
- ServicesExceptionNotHandledEventArgs.cs
- Win32KeyboardDevice.cs
- ProcessStartInfo.cs
- PartialTrustVisibleAssembly.cs
- MsmqInputSessionChannel.cs
- SingleQueryOperator.cs
- EntityDataSourceConfigureObjectContext.cs
- Clock.cs
- TextUtf8RawTextWriter.cs
- CodeSnippetTypeMember.cs
- DateTimeParse.cs
- ResourceAttributes.cs
- AssemblyCollection.cs
- contentDescriptor.cs
- TemplatedAdorner.cs
- ScrollItemPattern.cs
- DelegateInArgument.cs
- DesignTimeData.cs
- SortDescriptionCollection.cs
- OperationResponse.cs
- HttpPostedFile.cs
- MenuItemCollection.cs
- NameScopePropertyAttribute.cs
- MSG.cs
- BamlStream.cs
- ComponentResourceKey.cs
- LambdaExpression.cs
- GPRECTF.cs
- DrawingContextWalker.cs
- XmlAttributeAttribute.cs
- GridEntry.cs
- ExpandSegmentCollection.cs
- TypeConverterHelper.cs
- NamespaceMapping.cs
- WebPartsPersonalization.cs
- DataKey.cs
- RepeatInfo.cs
- SemanticAnalyzer.cs
- HttpApplication.cs
- TypeGeneratedEventArgs.cs
- PersonalizationState.cs
- DataObjectCopyingEventArgs.cs