Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / cdf / src / NetFx40 / Tools / System.Activities.Presentation / System / Activities / Presentation / WorkflowItemPresenter.cs / 1305376 / WorkflowItemPresenter.cs
//----------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//---------------------------------------------------------------
namespace System.Activities.Presentation
{
using System.Activities.Presentation.Model;
using System.Activities.Presentation.Services;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Threading;
using System.Activities.Presentation.View;
// This class provides a visual edit box to edit ModelItems. Textbox offers to edit strings, ints as a TextBlock and a cursor visually,
// The workflowitempresenter edits modelitems by picking their view using the view service. It presents s the visual for the modelitem
// pointe by Item property if it is set, it shows the hint text if the property is not set. It allows the associated item to be deleted
// visually , and removes the reference to Item when deleted. It also allows droping ModelItems, to set the Item property to the dropped
// item.
public sealed class WorkflowItemPresenter : ContentControl, ICompositeView
{
public static readonly DependencyProperty HintTextProperty =
DependencyProperty.Register("HintText", typeof(string), typeof(WorkflowItemPresenter), new UIPropertyMetadata(String.Empty));
public static readonly DependencyProperty ItemProperty =
DependencyProperty.Register("Item", typeof(ModelItem), typeof(WorkflowItemPresenter), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(WorkflowItemPresenter.OnItemChanged)));
public static readonly DependencyProperty AllowedItemTypeProperty =
DependencyProperty.Register("AllowedItemType", typeof(Type), typeof(WorkflowItemPresenter), new UIPropertyMetadata(typeof(object)));
public static readonly DependencyProperty IsDefaultContainerProperty =
DependencyProperty.Register("IsDefaultContainer", typeof(bool), typeof(WorkflowItemPresenter), new UIPropertyMetadata(false));
public static readonly DependencyProperty DroppingTypeResolvingOptionsProperty =
DependencyProperty.Register("DroppingTypeResolvingOptions", typeof(TypeResolvingOptions), typeof(WorkflowItemPresenter));
Grid contentGrid;
TextBlock text;
EditingContext context = null;
bool shouldSetFocus = false;
bool isItemPastedOrDropped = false;
public WorkflowItemPresenter()
{
contentGrid = new Grid();
text = new TextBlock();
text.SetBinding(TextBlock.TextProperty, "HintText");
text.DataContext = this;
text.HorizontalAlignment = HorizontalAlignment.Center;
text.VerticalAlignment = VerticalAlignment.Center;
text.Foreground = new SolidColorBrush(SystemColors.GrayTextColor);
text.FontStyle = FontStyles.Italic;
contentGrid.Background = Brushes.Transparent;
contentGrid.Children.Add(text);
}
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
this.AllowDrop = true;
this.Content = contentGrid;
ICompositeViewEvents containerEvents = null;
bool isDefault = false;
this.Loaded += (s, eventArgs) =>
{
isDefault = this.IsDefaultContainer;
DependencyObject parent = VisualTreeHelper.GetParent(this);
while (null != parent && !typeof(ICompositeViewEvents).IsAssignableFrom(parent.GetType()))
{
parent = VisualTreeHelper.GetParent(parent);
}
containerEvents = parent as ICompositeViewEvents;
if (null != containerEvents)
{
if (isDefault)
{
containerEvents.RegisterDefaultCompositeView(this);
}
else
{
containerEvents.RegisterCompositeView(this);
}
}
this.shouldSetFocus = true;
};
this.Unloaded += (s, eventArgs) =>
{
if (null != containerEvents)
{
if (isDefault)
{
containerEvents.UnregisterDefaultCompositeView(this);
}
else
{
containerEvents.UnregisterCompositeView(this);
}
}
this.shouldSetFocus = false;
};
}
public string HintText
{
get { return (string)GetValue(HintTextProperty); }
set { SetValue(HintTextProperty, value); }
}
[Fx.Tag.KnownXamlExternal]
public ModelItem Item
{
get { return (ModelItem)GetValue(ItemProperty); }
set { SetValue(ItemProperty, value); }
}
public Type AllowedItemType
{
get { return (Type)GetValue(AllowedItemTypeProperty); }
set { SetValue(AllowedItemTypeProperty, value); }
}
[Fx.Tag.KnownXamlExternal]
public TypeResolvingOptions DroppingTypeResolvingOptions
{
get { return (TypeResolvingOptions)GetValue(DroppingTypeResolvingOptionsProperty); }
set { SetValue(DroppingTypeResolvingOptionsProperty, value); }
}
EditingContext Context
{
get
{
if (context == null)
{
IModelTreeItem modelTreeItem = this.Item as IModelTreeItem;
if (modelTreeItem != null)
{
this.context = modelTreeItem.ModelTreeManager.Context;
}
else // There is no ModelItem yet, try to walk up the tree to find a WorkflowViewElement.
{
WorkflowViewElement parentViewElement = GetParentWorkflowViewElement();
if (parentViewElement != null)
{
this.context = parentViewElement.Context;
}
}
}
return context;
}
}
public bool IsDefaultContainer
{
get { return (bool)GetValue(IsDefaultContainerProperty); }
set { SetValue(IsDefaultContainerProperty, value); }
}
protected override void OnRender(DrawingContext drawingContext)
{
CutCopyPasteHelper.RegisterWithParentViewElement(this);
base.OnRender(drawingContext);
}
private WorkflowViewElement GetParentWorkflowViewElement()
{
// Walk the logic tree first.
FrameworkElement parent = (FrameworkElement)this.Parent;
while (parent != null && !(parent is WorkflowViewElement))
{
parent = parent.Parent as FrameworkElement;
}
WorkflowViewElement result = parent as WorkflowViewElement;
// If not found, walk the visual tree.
if (null == result)
{
parent = VisualTreeHelper.GetParent(this) as FrameworkElement;
while (parent != null && !(parent is WorkflowViewElement))
{
parent = VisualTreeHelper.GetParent(parent) as FrameworkElement;
}
result = parent as WorkflowViewElement;
}
return result;
}
static void OnItemChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
WorkflowItemPresenter control = (WorkflowItemPresenter)dependencyObject;
control.OnItemChanged(e);
}
void OnItemChanged(DependencyPropertyChangedEventArgs e)
{
object newItem = e.NewValue;
PopulateContent();
if (newItem != null)
{
//We want to set the selection only if the item is dropped or pasted.
//We cannot set the selection in UpdateItem, since while pasting that would still be in EditingScope and this.Item will be null.
if (this.isItemPastedOrDropped)
{
Fx.Assert(this.Item != null, "Item cannot be null");
// If we are currently moving from somewhere else to a WorkflowItemPresenter, the currently
// focusing view element will be removed, we need to set the keyboard focus explicitly to
// avoid WPF FocusManager to focus on an element, leading to flashing effect.
Keyboard.Focus((UIElement)this.Item.View);
this.isItemPastedOrDropped = false;
}
if (this.shouldSetFocus)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)(() =>
{
// check for Item == null, we found an interesting bug, where the user
// could drop something in here, and undo the change before the code below
// could execute
if (this.Item != null)
{
UIElement view = (UIElement)(this.Item.View);
if (view != null)
{
Keyboard.Focus(view);
Selection.SelectOnly(this.Context, this.Item);
}
}
//this.shouldSetFocus = false;
}));
}
}
else
{
// remove the selection if the previous value was selected.
if (this.Context != null)
{
if (this.Context.Items.GetValue().SelectedObjects.Contains(e.OldValue))
{
this.Context.Items.SetValue(new Selection(new ModelItem[] { }));
}
}
}
}
void PopulateContent()
{
if (this.Item != null)
{
VirtualizedContainerService containerService = this.Context.Services.GetService();
UIElement itemView = containerService.GetContainer(this.Item, this);
this.contentGrid.Children.Clear();
this.contentGrid.Children.Add(itemView);
}
else
{
contentGrid.Children.Clear();
contentGrid.Children.Add(text);
}
}
bool UpdateItem(object newItem)
{
bool updateSucceeded = false;
ModelItem newModelItem = newItem as ModelItem;
if (this.Item == null)
{
if (newModelItem == null && newItem != null)
{
// try to wrap the droppedObject in a ModelItem.
ModelServiceImpl modelService = (ModelServiceImpl)this.Context.Services.GetService();
newModelItem = modelService.WrapAsModelItem(newItem);
}
if (this.CanUpdateItem(newModelItem))
{
// In order to allow for model updates that happens during the model item is drop, this is all done in an atomic unit.
using (ModelEditingScope editingScope = this.Context.Services.GetService().Root.BeginEdit(SR.PropertyChangeEditingScopeDescription))
{
this.Item = newModelItem;
editingScope.Complete();
}
updateSucceeded = true;
this.isItemPastedOrDropped = true;
}
}
return updateSucceeded;
}
bool CanUpdateItem(ModelItem newModelItem)
{
return null != newModelItem && this.AllowedItemType.IsAssignableFrom(newModelItem.ItemType) && !this.IsInParentChain(newModelItem);
}
protected override void OnDrop(DragEventArgs e)
{
object droppedObject = DragDropHelper.GetDroppedObject(this, e, Context);
DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.None);
if (UpdateItem(droppedObject))
{
e.Handled = true;
DragDropHelper.SetDragDropCompletedEffects(e, DragDropEffects.Move);
}
base.OnDrop(e);
}
void OnDrag(DragEventArgs e)
{
if (!e.Handled)
{
if (null != this.Item || !DragDropHelper.AllowDrop(e.Data, this.Context, this.AllowedItemType))
{
e.Effects = DragDropEffects.None;
}
e.Handled = true;
}
}
protected override void OnDragEnter(DragEventArgs e)
{
this.OnDrag(e);
base.OnDragEnter(e);
}
protected override void OnDragOver(DragEventArgs e)
{
this.OnDrag(e);
base.OnDragOver(e);
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
// Schedule the Keyboard.Focus command to let it execute later than WorkflowViewElement.OnMouseDown,
// where WorkflowViewElement will move the keyboard focus on itself
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() =>
{
Keyboard.Focus((FrameworkElement)this);
}));
base.OnMouseDown(e);
}
private bool IsInParentChain(ModelItem droppedModelItem)
{
bool isInParentChain = false;
// start with immediate workflowviewElement outside this.
WorkflowViewElement parentViewElement = GetParentWorkflowViewElement();
if (parentViewElement != null)
{
ModelItem parentModelItem = parentViewElement.ModelItem;
while (parentModelItem != null)
{
if (parentModelItem == droppedModelItem)
{
isInParentChain = true;
break;
}
parentModelItem = parentModelItem.Parent;
}
}
return isInParentChain;
}
void DeleteItem()
{
this.Item = null;
this.PopulateContent();
}
void ICompositeView.OnItemMoved(ModelItem modelItem)
{
if (this.Item == modelItem)
{
this.Item = null;
}
}
protected override AutomationPeer OnCreateAutomationPeer()
{
return new WorkflowItemPresenterAutomationPeer(this);
}
object ICompositeView.OnItemsCut(List itemsToCut)
{
Fx.Assert(itemsToCut.Count == 1, "Only one item can be cut");
Fx.Assert(itemsToCut[0].Equals(this.Item), "Only one item can be cut.");
this.DeleteItem();
return null;
}
object ICompositeView.OnItemsCopied(List itemsToCopy)
{
return null;
}
void ICompositeView.OnItemsPasted(List
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Rules.cs
- CompensatableSequenceActivity.cs
- VisualTreeHelper.cs
- StrongNamePublicKeyBlob.cs
- LogSwitch.cs
- LinkButton.cs
- TrustSection.cs
- RectAnimationUsingKeyFrames.cs
- PngBitmapDecoder.cs
- backend.cs
- SerializationObjectManager.cs
- HtmlContainerControl.cs
- DoubleKeyFrameCollection.cs
- ConfigurationPropertyAttribute.cs
- KeyFrames.cs
- ServicesUtilities.cs
- ParserHooks.cs
- KeyManager.cs
- ScriptManagerProxy.cs
- PageCatalogPart.cs
- SecurityUniqueId.cs
- PageBuildProvider.cs
- DrawingAttributesDefaultValueFactory.cs
- GenericWebPart.cs
- UnmanagedMemoryStream.cs
- ShapingWorkspace.cs
- BooleanFunctions.cs
- SelectionGlyphBase.cs
- ActivityLocationReferenceEnvironment.cs
- ScrollableControl.cs
- GradientSpreadMethodValidation.cs
- SqlNodeAnnotation.cs
- TemplatedAdorner.cs
- HttpListenerContext.cs
- WindowsSpinner.cs
- BoolExpressionVisitors.cs
- LinkAreaEditor.cs
- ProtocolsSection.cs
- XmlILModule.cs
- XmlToDatasetMap.cs
- _KerberosClient.cs
- ValidatingPropertiesEventArgs.cs
- ObjectItemConventionAssemblyLoader.cs
- DataListItemEventArgs.cs
- RoutedUICommand.cs
- ManipulationLogic.cs
- PointF.cs
- HtmlInputPassword.cs
- DataSourceCacheDurationConverter.cs
- ExpressionConverter.cs
- HttpRequestTraceRecord.cs
- Types.cs
- precedingsibling.cs
- ObjectDataSource.cs
- ObjectStorage.cs
- CodeAccessPermission.cs
- ApplicationInterop.cs
- BuilderElements.cs
- ScrollPattern.cs
- RelativeSource.cs
- PeerContact.cs
- ParagraphResult.cs
- BufferedGraphicsContext.cs
- WebPartCatalogAddVerb.cs
- Timer.cs
- TransformedBitmap.cs
- BitStream.cs
- MemberInfoSerializationHolder.cs
- GeneratedContractType.cs
- ValueUtilsSmi.cs
- StylusDownEventArgs.cs
- TrackingServices.cs
- XmlSchemaDocumentation.cs
- WindowsTitleBar.cs
- EventDescriptor.cs
- Invariant.cs
- Hyperlink.cs
- DataKeyPropertyAttribute.cs
- ConfigurationStrings.cs
- WorkflowCreationContext.cs
- SmiRequestExecutor.cs
- HttpCookieCollection.cs
- SiteMapNodeItem.cs
- FormsIdentity.cs
- SpAudioStreamWrapper.cs
- ZipIOEndOfCentralDirectoryBlock.cs
- ControlParser.cs
- WasAdminWrapper.cs
- CqlGenerator.cs
- WindowsAuthenticationEventArgs.cs
- Logging.cs
- DocumentGridContextMenu.cs
- Rotation3D.cs
- ListBox.cs
- GenericWebPart.cs
- SapiRecoContext.cs
- Wizard.cs
- ShapingWorkspace.cs
- NativeActivityAbortContext.cs
- KeySpline.cs