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
- XPathParser.cs
- ImageAutomationPeer.cs
- PartialCachingControl.cs
- MemoryMappedView.cs
- WebPartPersonalization.cs
- RecommendedAsConfigurableAttribute.cs
- TextAdaptor.cs
- codemethodreferenceexpression.cs
- ObjectListDesigner.cs
- XmlSchemaElement.cs
- RadialGradientBrush.cs
- SizeAnimationUsingKeyFrames.cs
- MasterPageParser.cs
- QueryStatement.cs
- SectionInput.cs
- LayoutEvent.cs
- DataBoundLiteralControl.cs
- WhitespaceRuleReader.cs
- ListSortDescriptionCollection.cs
- SafeArrayRankMismatchException.cs
- NamedObject.cs
- CodeDirectiveCollection.cs
- ReaderWriterLockWrapper.cs
- HttpConfigurationSystem.cs
- NavigationProperty.cs
- HtmlProps.cs
- linebase.cs
- HtmlSelect.cs
- MeasureItemEvent.cs
- Exception.cs
- TextFindEngine.cs
- EntityDataSourceContextDisposingEventArgs.cs
- DesignTimeVisibleAttribute.cs
- ImageSourceValueSerializer.cs
- InfoCardRSAPKCS1SignatureDeformatter.cs
- ColumnWidthChangingEvent.cs
- Memoizer.cs
- WrappedReader.cs
- ServicePoint.cs
- Int16.cs
- Vector3DIndependentAnimationStorage.cs
- CompletionBookmark.cs
- DefaultValueTypeConverter.cs
- formatter.cs
- BinaryFormatterWriter.cs
- StyleSheet.cs
- MultipleFilterMatchesException.cs
- InertiaExpansionBehavior.cs
- XmlILConstructAnalyzer.cs
- DetailsViewCommandEventArgs.cs
- CodeDOMProvider.cs
- TextPenaltyModule.cs
- ExcludePathInfo.cs
- EventRouteFactory.cs
- GlyphRun.cs
- Contracts.cs
- ScalarType.cs
- FtpCachePolicyElement.cs
- ItemType.cs
- SharedConnectionListener.cs
- ExtensionFile.cs
- CodeEventReferenceExpression.cs
- TreeNodeMouseHoverEvent.cs
- WorkflowRuntime.cs
- FieldNameLookup.cs
- DateTimePicker.cs
- SegmentInfo.cs
- RegexRunner.cs
- OdbcCommand.cs
- OleDbStruct.cs
- loginstatus.cs
- ResolveNameEventArgs.cs
- XmlDataLoader.cs
- SocketConnection.cs
- FontCacheLogic.cs
- SmiMetaData.cs
- DataGridViewCellPaintingEventArgs.cs
- DataGridViewElement.cs
- SchemaElementLookUpTable.cs
- StringValueSerializer.cs
- UniqueConstraint.cs
- TransactionChannelListener.cs
- TextServicesCompartment.cs
- IndentedWriter.cs
- DesignerObjectListAdapter.cs
- WebHttpEndpoint.cs
- ToolStripPanelCell.cs
- HostProtectionException.cs
- ObjectView.cs
- UserPreferenceChangedEventArgs.cs
- RubberbandSelector.cs
- AesCryptoServiceProvider.cs
- SQLDecimal.cs
- SqlClientWrapperSmiStreamChars.cs
- DataGridViewBand.cs
- Debug.cs
- WorkflowMarkupSerializer.cs
- DataGridViewDataConnection.cs
- ContainerParagraph.cs
- ViewValidator.cs