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
- MappingSource.cs
- ProcessingInstructionAction.cs
- TCPListener.cs
- OdbcConnectionPoolProviderInfo.cs
- BuildProviderUtils.cs
- WebPartDescription.cs
- KeyConverter.cs
- SchemaTableOptionalColumn.cs
- SqlCacheDependencyDatabase.cs
- WebPartTracker.cs
- Console.cs
- Peer.cs
- TemplateBindingExtensionConverter.cs
- HttpConfigurationSystem.cs
- SoapClientProtocol.cs
- UrlRoutingHandler.cs
- QueueException.cs
- IteratorFilter.cs
- SqlUserDefinedAggregateAttribute.cs
- ToolStripButton.cs
- SqlTrackingQuery.cs
- HMACMD5.cs
- BrowserCapabilitiesFactory.cs
- PropertyGridEditorPart.cs
- AttributeParameterInfo.cs
- ProfilePropertySettingsCollection.cs
- TemplateLookupAction.cs
- InvariantComparer.cs
- ExtendedTransformFactory.cs
- DependencyPropertyAttribute.cs
- MetadataSource.cs
- FontInfo.cs
- PropertyCondition.cs
- TimeSpanStorage.cs
- ZoomingMessageFilter.cs
- List.cs
- ColumnReorderedEventArgs.cs
- DictionarySectionHandler.cs
- GuidelineCollection.cs
- XMLUtil.cs
- configsystem.cs
- XmlUtilWriter.cs
- SuppressMergeCheckAttribute.cs
- StringWriter.cs
- SmiConnection.cs
- XmlArrayItemAttributes.cs
- NameService.cs
- Debug.cs
- Module.cs
- ReservationCollection.cs
- TimeSpanStorage.cs
- RadioButtonPopupAdapter.cs
- XmlReaderDelegator.cs
- GlyphCollection.cs
- Int32CollectionValueSerializer.cs
- CodeTypeConstructor.cs
- TextTreeFixupNode.cs
- ExpressionNode.cs
- SR.cs
- MailAddress.cs
- Missing.cs
- ToolStripTemplateNode.cs
- PenCursorManager.cs
- VisualStyleInformation.cs
- UnsafeNativeMethods.cs
- Formatter.cs
- ConstraintConverter.cs
- CompensateDesigner.cs
- BuildProvider.cs
- BamlRecords.cs
- StylusPoint.cs
- OdbcDataAdapter.cs
- BackgroundWorker.cs
- PhysicalFontFamily.cs
- DBSchemaTable.cs
- ReadOnlyDataSourceView.cs
- GridViewRow.cs
- DynamicDataExtensions.cs
- DataPagerFieldCommandEventArgs.cs
- Expressions.cs
- AsyncInvokeOperation.cs
- SqlParameter.cs
- DataGridComponentEditor.cs
- AnonymousIdentificationModule.cs
- SapiRecognizer.cs
- XMLSchema.cs
- TypeDescriptionProviderAttribute.cs
- ComponentEvent.cs
- Material.cs
- ResourceType.cs
- DataGridViewColumnConverter.cs
- PackageRelationshipCollection.cs
- IResourceProvider.cs
- FixedPage.cs
- Graphics.cs
- SizeValueSerializer.cs
- TransformCollection.cs
- ToolStripLabel.cs
- ChangeToolStripParentVerb.cs
- DBNull.cs