private ModelItem FindModelItemToFocus(ModelItem itemToFocus) { WorkflowViewService viewService = this.WorkflowViewService; if (viewService == null || itemToFocus == null) { return(itemToFocus); } ModelUtilities.ReverseTraverse(itemToFocus, (ModelItem modelItem) => { if (modelItem == null) { // continue; return(true); } // if the item has Designer, we assume it can get focus. if (CanFocusOnModelItem(modelItem, viewService)) { itemToFocus = modelItem; // break; return(false); } // continue return(true); }); return(itemToFocus); }
public override void Initialize(EditingContext context) { this.context = context; AttachedPropertiesService propertiesService = this.context.Services.GetService<AttachedPropertiesService>(); helpService = this.context.Services.GetService<IIntegratedHelpService>(); oldSelection = this.context.Items.GetValue<Selection>(); isPrimarySelectionProperty = new AttachedProperty<bool>() { Getter = (modelItem) => (this.context.Items.GetValue<Selection>().PrimarySelection == modelItem), Name = "IsPrimarySelection", OwnerType = typeof(Object) }; isSelectionProperty = new AttachedProperty<bool>() { Getter = (modelItem) => (((IList)this.context.Items.GetValue<Selection>().SelectedObjects).Contains(modelItem)), Name = "IsSelection", OwnerType = typeof(Object) }; propertiesService.AddProperty(isPrimarySelectionProperty); propertiesService.AddProperty(isSelectionProperty); if (this.context.Services.GetService<ViewService>() == null) { view = new System.Activities.Presentation.View.DesignerView(this.context); WorkflowViewService viewService = new WorkflowViewService(context); WorkflowViewStateService viewStateService = new WorkflowViewStateService(context); this.context.Services.Publish<ViewService>(viewService); this.context.Services.Publish<VirtualizedContainerService>(new VirtualizedContainerService(this.context)); this.context.Services.Publish<ViewStateService>(viewStateService); this.context.Services.Publish<DesignerView>(view); WorkflowAnnotationAdornerService annotationService = new WorkflowAnnotationAdornerService(); annotationService.Initialize(this.context, view.scrollViewer); this.context.Services.Publish<AnnotationAdornerService>(annotationService); this.context.Services.Subscribe<ModelService>(delegate(ModelService modelService) { this.modelService = modelService; if (modelService.Root != null) { view.MakeRootDesigner(modelService.Root); } view.RestoreDesignerStates(); this.context.Items.Subscribe<Selection>(new SubscribeContextCallback<Selection>(OnItemSelected)); }); } if (helpService != null) { helpService.AddContextAttribute(string.Empty, KeywordForWorkflowDesignerHomePage, HelpKeywordType.F1Keyword); } }
static Type ResolveGenericParameters(DependencyObject dropTarget, EditingContext context, Type type) { // look to see if there is a DefaultTypeArgumentAttribute on it DefaultTypeArgumentAttribute typeArgumentAttribute = ExtensibilityAccessor.GetAttribute <DefaultTypeArgumentAttribute>(type); if (typeArgumentAttribute != null && typeArgumentAttribute.Type != null) { type = type.MakeGenericType(typeArgumentAttribute.Type); } else //require user to resolve generic arguments { ActivityTypeResolver wnd = new ActivityTypeResolver(); if (null != context) { WindowHelperService service = context.Services.GetService <WindowHelperService>(); if (null != service) { service.TrySetWindowOwner(dropTarget, wnd); } } TypeResolvingOptions dropTargetOptions = null; TypeResolvingOptions activityTypeOptions = null; //try to see if the container has any customization for type resolver ICompositeView container = dropTarget as ICompositeView; if (container != null) { dropTargetOptions = container.DroppingTypeResolvingOptions; } //try to see if the activity type in discourse has any customization for type resolver TypeResolvingOptionsAttribute attr = WorkflowViewService.GetAttribute <TypeResolvingOptionsAttribute>(type); if (attr != null) { activityTypeOptions = attr.TypeResolvingOptions; } //if both have type resolver, try to merge them TypeResolvingOptions options = TypeResolvingOptions.Merge(dropTargetOptions, activityTypeOptions); if (options != null) { wnd.Options = options; } wnd.Context = context; wnd.EditedType = type; wnd.Width = 340; wnd.Height = 200; type = (true == wnd.ShowDialog() ? wnd.ConcreteType : null); } return(type); }
private static bool CanFocusOnModelItem(ModelItem itemToFocus, WorkflowViewService viewService) { Fx.Assert(itemToFocus != null && viewService != null, "null argument"); if (typeof(ITextExpression).IsAssignableFrom(itemToFocus.ItemType)) { return(false); } Type designerType = viewService.GetDesignerType(itemToFocus.ItemType); return(typeof(WorkflowViewElement).IsAssignableFrom(designerType)); }
private static bool ModelItemHasDesigner(ModelItem modelItem) { if (modelItem != null) { DesignerAttribute attribute = WorkflowViewService.GetAttribute <DesignerAttribute>(modelItem.ItemType); if (attribute != null && !string.IsNullOrEmpty(attribute.DesignerTypeName)) { return(true); } } return(false); }
internal IEnumerable <ModelItem> GetItemsOnDesigner(bool preOrder, bool excludeRoot, bool excludeErrorActivity, bool excludeExpression, bool includeOtherObjects) { WorkflowViewService viewService = this.WorkflowViewService; IList <ModelItem> items = ModelTreeManager.DepthFirstSearch(modelService.Root, delegate(Type type) { // Only find items on the designer surface. return(includeOtherObjects || (typeof(WorkflowViewElement).IsAssignableFrom(viewService.GetDesignerType(type)))); }, delegate(ModelItem modelItem) { return(!(excludeExpression && modelItem != null && typeof(ITextExpression).IsAssignableFrom(modelItem.ItemType))); }, preOrder); // ModelItemKeyValuePair is associated with CaseDesigner. // So ModelItemKeyValuePair will be returned even if they are not really Cases. // Those ModelItemKeyValuePairs need to be excluded. IEnumerable <ModelItem> itemsToSearch = null; if (!excludeErrorActivity) { itemsToSearch = items.Where <ModelItem>(item => !ModelUtilities.IsModelItemKeyValuePair(item.ItemType) || ModelUtilities.IsSwitchCase(item)); } else { itemsToSearch = items.Where <ModelItem>(item => (!ModelUtilities.IsModelItemKeyValuePair(item.ItemType) || ModelUtilities.IsSwitchCase(item)) && !IsErrorActivity(item)); } if (excludeRoot) { itemsToSearch = itemsToSearch.Except <ModelItem>(new ModelItem[] { modelService.Root }); } return(itemsToSearch); }
private static bool CanFocusOnModelItem(ModelItem itemToFocus, WorkflowViewService viewService) { Fx.Assert(itemToFocus != null && viewService != null, "null argument"); if (typeof(ITextExpression).IsAssignableFrom(itemToFocus.ItemType)) { return false; } Type designerType = viewService.GetDesignerType(itemToFocus.ItemType); return typeof(WorkflowViewElement).IsAssignableFrom(designerType); }
// Entry point method for setting focus. // it is executed exactly once, on application idle event // there are 3 basic paths: // a) optimistic - element we are looking for, is visible - i bring it into view and set keyboard focus to it // b) unlikely - element doesn't have any visual parents - i make it a root designer, wait for it to load and set keyboard focus to it // c) pesimistic/complex - element isn't in the view, moreover, it is located in a tree branch which is not (or is partialy) visible void Focus() { //can i continue? if (shouldAbort) { return; } //hide the designer view until focus is set this.onSetDesignerContentVisibilityDelegate(Visibility.Hidden); //delegate visibility restore for designer view after focus update is complete Dispatcher.CurrentDispatcher.BeginInvoke(this.onSetDesignerContentVisibilityDelegate, DispatcherPriority.ApplicationIdle, Visibility.Visible); //set selection to the item to focus, so all apropriate designers get a chance to update themselfs before we start expanding - this may //result in visual tree change Selection.SelectOnly(this.Context, this.itemToFocus); //easy path - if the current designer is available and visible - bring it to view and focus if (null != this.itemToFocus.View && ((UIElement)this.itemToFocus.View).IsVisible) { this.onElementFocusingDelegate(this.itemToFocus); return; } //get items up to the tree root, which can be visualized (have associated designer) //include only up to "level" items (avoid expanding whole tree) bool shouldContinue = true; int visualItemsCount = 0; var visualItems = this.itemToFocus .GetParentEnumerator(p => shouldContinue) .Where(p => { //filter only items with designer attribute bool result = false; var designerType = this.ViewService.GetDesignerType(p.ItemType); if (null != designerType) { result = true; visualItemsCount++; //if designer has Options attribute, check if it always collapsed children - if so, this will be the topmost parent //(displaying anything above, will never display its children) var options = WorkflowViewService.GetAttribute <ActivityDesignerOptionsAttribute>(designerType); if (null != options && options.AlwaysCollapseChildren && visualItemsCount > 2) { shouldContinue = false; } } return(result); }) .Take(this.currentLevel) .ToArray(); //nothing to expand, rather unlikely, but handle it anyway if (visualItems.Length == 0) { //reset ticket, to prevent any further calls from executing ModelItemFocusHelper.focusTicket = null; //force item to be root designer (this is last resort, it is executed only if focusTicket is null) this.onForceElementFocusDelegate(); return; } //get the first parent of an item, which is visible var firstVisibleItem = visualItems.FirstOrDefault(p => null != p.View && ((UIElement)p.View).IsVisible); bool enqueueFirstExpand = false; //is there anything visible in the path between item and its parents? if (null != firstVisibleItem) { //yes - limit the amount of items to expand to only designers which are not visible yet //(include the first visible designer, so algorithm can have a start point with something visible) this.itemsToExpand = visualItems.TakeWhile(p => firstVisibleItem != p).Concat(new ModelItem[] { firstVisibleItem }).ToArray(); } else { //no, nothing is visible yet this.itemsToExpand = visualItems; enqueueFirstExpand = true; //make the top most parent as root designer this.DesignerView.MakeRootDesigner(this.itemsToExpand[this.itemsToExpand.Length - 1], false); } //delegate Expand call - if nothing is visible yet - onIdle - give new designer time to fully render, if someting is visible - execute immediatelly Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => { this.Expand(null); }), enqueueFirstExpand ? DispatcherPriority.ContextIdle : DispatcherPriority.Send); }
internal static bool IsBreakpointAllowed(Type breakpointCandidateType) { return(typeof(Activity).IsAssignableFrom(breakpointCandidateType) || WorkflowViewService.GetAttribute <AllowBreakpointAttribute>(breakpointCandidateType) != null); }
private void OnViewServiceAvailable(ViewService viewService) { this.viewService = (WorkflowViewService)viewService; this.viewService.ViewCreated += this.ViewCreated; }
private static bool HasView(ModelItem modelItem, WorkflowViewService viewService, bool allowDrillIn) { ActivityDesignerOptionsAttribute options = WorkflowViewService.GetAttribute<ActivityDesignerOptionsAttribute>(modelItem.ItemType); Type viewType = viewService.GetDesignerType(modelItem.ItemType); return typeof(WorkflowViewElement).IsAssignableFrom(viewType) && (!allowDrillIn || options == null || options.AllowDrillIn); }
public ErrorActivityView() { WorkflowViewService.ShowErrorInViewElement(this, SR.ActivityLoadError, null); }
private DrawingBrush GetIconByVisualValue() { if (this.VisualValue != null) { DrawingBrush icon = null; Type modelItemType = this.VisualValue.ItemType; if (modelItemType.IsGenericType) { // If Type is generic type, whatever T, it should display same icon, so use generic type instead. modelItemType = this.VisualValue.ItemType.GetGenericTypeDefinition(); } // If the user specifies the attribute, then the Designer would be providing the icon, // bypassing the pipeline of retrieving the icons via reflection and attached properties. ActivityDesignerOptionsAttribute attr = ExtensibilityAccessor.GetAttribute <ActivityDesignerOptionsAttribute>(modelItemType); if (attr != null && attr.OutlineViewIconProvider != null) { icon = attr.OutlineViewIconProvider(this.VisualValue); } if (icon == null && !TreeViewItemViewModel.IconCache.TryGetValue(modelItemType, out icon)) { EditingContext context = this.VisualValue.GetEditingContext(); ViewService service = context.Services.GetService <ViewService>(); WorkflowViewService workflowViewService = service as WorkflowViewService; ActivityDesigner designer = null; // first try to create an detached view element that won't participate in the designer, // if the view service is WorkflowViewService if (workflowViewService != null) { designer = workflowViewService.CreateDetachedViewElement(this.VisualValue) as ActivityDesigner; icon = GetIconFromUnInitializedDesigner(designer); } else { // fall back if the view service is not the default implementation // We only need to get the icon from the designer, so we don't need to make sure the view is parented. designer = this.VisualValue.View as ActivityDesigner; if (designer == null && service != null) { designer = service.GetView(this.VisualValue) as ActivityDesigner; } if (designer != null) { if (designer.Icon != null || designer.IsLoaded) { icon = designer.Icon; } else { icon = GetIconFromUnInitializedDesigner(designer); } } } // Cache even a null icon since answers found above won't change within this AppDomain TreeViewItemViewModel.IconCache.Add(modelItemType, icon); } return(icon); } else { return(null); } }