/// <summary> /// Sets the flags the visual has on a specific channel. /// </summary> internal void SetFlags( DUCE.Channel channel, bool value, VisualProxyFlags flags) { SetFlags(Find(channel) + 1, value, flags); // Find's results are -1 based, adjust by one. }
/// <summary> /// Sets the flags on all channels the visual is marshaled to. /// </summary> internal void SetFlagsOnAllChannels( bool value, VisualProxyFlags flags) { if (_head.Channel != null) { _head.Flags = value ? (_head.Flags | flags) : (_head.Flags & ~flags); for (int i = 0, limit = Count - 1; i < limit; i++) { _tail[i].Flags = value ? (_tail[i].Flags | flags) : (_tail[i].Flags & ~flags); } } }
//------------------------------------------------------ // // Constructors // //------------------------------------------------------ //------------------------------------------------------ // // Public Methods // //------------------------------------------------------ //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ //------------------------------------------------------ // // Public Events // //------------------------------------------------------ //------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods /// <summary> /// This walks up the Visual tree setting the given flags starting at the /// given element. /// </summary> internal static void PropagateFlags( DependencyObject element, VisualFlags flags, VisualProxyFlags proxyFlags) { Visual visual; Visual3D visual3D; AsVisualInternal(element, out visual, out visual3D); if (visual != null) { Visual.PropagateFlags(visual, flags, proxyFlags); } else { Visual3D.PropagateFlags(visual3D, flags, proxyFlags); } }
//----------------------------------------------------- // // Constructors // //----------------------------------------------------- //------------------------------------------------------ // // Public Methods // //----------------------------------------------------- //------------------------------------------------------ // // Public Properties // //------------------------------------------------------ //----------------------------------------------------- // // Public Events // //------------------------------------------------------ //----------------------------------------------------- // // Internal Methods // //----------------------------------------------------- #region Internal Methods /// <summary> /// This walks up the Visual tree setting the given flags starting at the /// given element. /// </summary> internal static void PropagateFlags( DependencyObject element, VisualFlags flags, VisualProxyFlags proxyFlags) { Visual visual; Visual3D visual3D; AsVisualInternal(element, out visual, out visual3D); if (visual != null) { Visual.PropagateFlags(visual, flags, proxyFlags); } else { Visual3D.PropagateFlags(visual3D, flags, proxyFlags); } }
/// <summary> /// Sets the flags the visual has on the n-th channel. /// </summary> internal void SetFlags( int index, bool value, VisualProxyFlags flags) { Debug.Assert(index >= 0 && index < Count); if (index < Count) { if (index == 0) { _head.Flags = value ? (_head.Flags | flags) : (_head.Flags & ~flags); } else if (index > 0) { _tail[index - 1].Flags = value ? (_tail[index - 1].Flags | flags) : (_tail[index - 1].Flags & ~flags); } } }
/// <summary> /// Returns true if the given flags are set for every proxy or if /// the visual is not being marshaled. /// </summary> internal bool CheckFlagsOnAllChannels( VisualProxyFlags conjunctionFlags) { if (_head.Channel != null) { if ((_head.Flags & conjunctionFlags) != conjunctionFlags) { return(false); } for (int i = 0, limit = Count - 1; i < limit; i++) { if ((_tail[i].Flags & conjunctionFlags) != conjunctionFlags) { return(false); } } } return(true); }
/// <summary> /// Propagates the flags up to the root. /// </summary> /// <remarks> /// The walk stops on a node with all of the required flags set. /// </remarks> internal static void PropagateFlags( Visual e, VisualFlags flags, VisualProxyFlags proxyFlags) { while ((e != null) && (!e.CheckFlagsAnd(flags) || !e.CheckFlagsOnAllChannels(proxyFlags))) { if (e.CheckFlagsOr(VisualFlags.ShouldPostRender)) { MediaContext mctx = MediaContext.From(e.Dispatcher); if (mctx.Channel != null) { mctx.PostRender(); } } else if (e.CheckFlagsAnd(VisualFlags.NodeIsCyclicBrushRoot)) { // // For visuals that are root nodes in visual brushes we // need to fire OnChanged on the owning brushes. // Dictionary<ICyclicBrush, int> cyclicBrushToChannelsMap = CyclicBrushToChannelsMapField.GetValue(e); Debug.Assert(cyclicBrushToChannelsMap != null, "Visual brush roots need to have the visual brush to channels map!"); // // Iterate over the visual brushes and fire the OnChanged event. // foreach (ICyclicBrush cyclicBrush in cyclicBrushToChannelsMap.Keys) { cyclicBrush.FireOnChanged(); } } e.SetFlags(true, flags); e.SetFlagsOnAllChannels(true, proxyFlags); if (e._parent == null) { // Stop propagating. We are at the root of the 2D subtree. return; } Visual parentAsVisual = e._parent as Visual; if (parentAsVisual == null) { // if the parent is not null (saw this with earlier null check) and is not a Visual // it must be a Visual3D - continue the propagation Visual3D.PropagateFlags((Visual3D)e._parent, flags, proxyFlags); return; } e = parentAsVisual; } }
/// <summary> /// Disconnects a resource attached to this visual. /// </summary> internal void DisconnectAttachedResource( VisualProxyFlags correspondingFlag, DUCE.IResource attachedResource) { // // Iterate over the channels this visual is being marshaled to // for (int i = 0; i < _proxy.Count; i++) { VisualProxyFlags flags = _proxy.GetFlags(i); if ((flags & correspondingFlag) == 0) { DUCE.Channel channel = _proxy.GetChannel(i); // // Set the flag so that during render we send // update to the compositor. // SetFlags(channel, true, correspondingFlag); if (correspondingFlag == VisualProxyFlags.IsContentDirty) { _proxy.SetFlags(i, false, VisualProxyFlags.IsContentConnected); } attachedResource.ReleaseOnChannel(channel); } } }
/// <summary> /// Update opacity /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel"></param> private void UpdateOpacity(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { // Opacity ---------------------------------------------------------------------------- if ((flags & VisualProxyFlags.IsOpacityDirty) != 0) { double opacity = OpacityField.GetValue(this); if (isOnChannel || !(opacity >= 1.0)) { // // Opacity is 1.0 by default -- do not send it for new visuals. // DUCE.CompositionNode.SetAlpha( handle, opacity, channel); } SetFlags(channel, false, VisualProxyFlags.IsOpacityDirty); } }
/// <summary> /// Disconnects a resource attached to this visual. /// </summary> internal void DisconnectAttachedResource( VisualProxyFlags correspondingFlag, DUCE.IResource attachedResource) { // // We need a special case for the content (corresponding // to the IsContentConnected flag). // bool needToReleaseContent = correspondingFlag == VisualProxyFlags.IsContentConnected; // // Iterate over the channels this visual is being marshaled to // for (int i = 0; i < _proxy.Count; i++) { DUCE.Channel channel = _proxy.GetChannel(i); VisualProxyFlags flags = _proxy.GetFlags(i); // // See if the corresponding flag is set... // bool correspondingFlagSet = (flags & correspondingFlag) != 0; // // We want to perform an action if IsContentConnected // flag is set or a Is*Dirty flag is not set: // if (correspondingFlagSet == needToReleaseContent) { // // Set the flag so that during render we send // update to the compositor. // SetFlags(channel, true, correspondingFlag); attachedResource.ReleaseOnChannel(channel); if (needToReleaseContent) { // // Mark the content of this visual as disconnected. // _proxy.SetFlags(i, false, VisualProxyFlags.IsContentConnected); } } } }
/// <summary> /// Checks if any of the specified flags is set on a given channel. /// </summary> /// <remarks> /// If there aren't any bits set on the specified flags /// the method returns true. /// </remarks> internal bool CheckFlagsOr( DUCE.Channel channel, VisualProxyFlags flagsToCheck) { return (_proxy.GetFlags(channel) & flagsToCheck) != VisualProxyFlags.None; }
/// <summary> /// Update scrollable area clip /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel">The Visual exists on channel.</param> private void UpdateScrollableAreaClip(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { if ((flags & VisualProxyFlags.IsScrollableAreaClipDirty) != 0) { Rect? scrollableArea = ScrollableAreaClipField.GetValue(this); if (isOnChannel || (scrollableArea != null)) { DUCE.CompositionNode.SetScrollableAreaClip( handle, scrollableArea, channel); } SetFlags(channel, false, VisualProxyFlags.IsScrollableAreaClipDirty); } }
/// <summary> /// CheckFlagsOnAllChannels returns true if all flags in /// the bitmask flags are set on all channels this visual is /// marshaled to. /// </summary> /// <remarks> /// If there aren't any bits set on the specified flags /// the method returns true. /// </remarks> internal bool CheckFlagsOnAllChannels(VisualProxyFlags flagsToCheck) { return _proxy.CheckFlagsOnAllChannels(flagsToCheck); }
/// <summary> /// Update cache mode. /// </summary> private void UpdateCacheMode(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { // Cache Mode ------------------------------------------------------------------------------- if ((flags & VisualProxyFlags.IsCacheModeDirty) != 0) { CacheMode cacheMode = CacheModeField.GetValue(this); if (cacheMode != null) { // // Set the new cache mode resource on the visual. // If cacheMode is null we don't need to do this. // Also note that the old cache mode was disconnected // in the CacheMode property setter. // DUCE.CompositionNode.SetCacheMode( handle, ((DUCE.IResource)cacheMode).AddRefOnChannel(channel), channel); } else if (isOnChannel) /* cacheMode == null */ { DUCE.CompositionNode.SetCacheMode( handle, DUCE.ResourceHandle.Null, channel); } SetFlags(channel, false, VisualProxyFlags.IsCacheModeDirty); } }
/// <summary> /// Update clip /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel">The Visual exists on channel.</param> private void UpdateClip(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { // Clip ------------------------------------------------------------------------------------ if ((flags & VisualProxyFlags.IsClipDirty) != 0) { Geometry clip = ClipField.GetValue(this); if (clip != null) { // // Set the new clip resource on the composition node. // If clip is null we don't need to do this. Also note // that the old clip was disconnected in the Clip // property setter. // DUCE.CompositionNode.SetClip( handle, ((DUCE.IResource)clip).AddRefOnChannel(channel), channel); } else if (isOnChannel) /* clip == null */ { DUCE.CompositionNode.SetClip( handle, DUCE.ResourceHandle.Null, channel); } SetFlags(channel, false, VisualProxyFlags.IsClipDirty); } }
/// Update effect. /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel">The Visual exists on channel.</param> private void UpdateEffect(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { // Effect ------------------------------------------------------------------------------- if ((flags & VisualProxyFlags.IsEffectDirty) != 0) { Effect effect = EffectField.GetValue(this); if (effect != null) { // // Set the new effect resource on the visual. // If effect is null we don't need to do this. // Also note that the old effect was disconnected // in the Effect property setter. // DUCE.CompositionNode.SetEffect( handle, ((DUCE.IResource)effect).AddRefOnChannel(channel), channel); } else if (isOnChannel) /* effect == null */ { DUCE.CompositionNode.SetEffect( handle, DUCE.ResourceHandle.Null, channel); } SetFlags(channel, false, VisualProxyFlags.IsEffectDirty); } }
/// <summary> /// Update transform /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel">The Visual exists on channel.</param> private void UpdateTransform(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { // Transform ------------------------------------------------------------------------------- if ((flags & VisualProxyFlags.IsTransformDirty) != 0) { Transform transform = TransformField.GetValue(this); if (transform != null) { // // Set the new transform resource on the visual. // If transform is null we don't need to do this. // Also note that the old transform was disconnected // in the Transform property setter. // DUCE.CompositionNode.SetTransform( handle, ((DUCE.IResource)transform).AddRefOnChannel(channel), channel); } else if (isOnChannel) /* transform == null */ { DUCE.CompositionNode.SetTransform( handle, DUCE.ResourceHandle.Null, channel); } SetFlags(channel, false, VisualProxyFlags.IsTransformDirty); } }
/// <summary> /// Update OpacityMask /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel">The Visual exists on channel.</param> private void UpdateOpacityMask(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { // Opacity Mask ---------------------------------------------------------------------------- if ((flags & VisualProxyFlags.IsOpacityMaskDirty) != 0) { Brush opacityMask = OpacityMaskField.GetValue(this); if (opacityMask != null) { // // Set the new opacity mask resource on the visual. // If opacityMask is null we don't need to do this. // Also note that the old opacity mask was disconnected // in the OpacityMask property setter. // DUCE.CompositionNode.SetAlphaMask( handle, ((DUCE.IResource)opacityMask).AddRefOnChannel(channel), channel); } else if (isOnChannel) /* opacityMask == null */ { DUCE.CompositionNode.SetAlphaMask( handle, DUCE.ResourceHandle.Null, channel); } SetFlags(channel, false, VisualProxyFlags.IsOpacityMaskDirty); } }
// -------------------------------------------------------------------- // // Visual flags manipulation // // -------------------------------------------------------------------- #region Visual flags manipulation /// <summary> /// SetFlagsOnAllChannels is used to set or unset one /// or multiple flags on all channels this visual is /// marshaled to. /// </summary> internal void SetFlagsOnAllChannels( bool value, VisualProxyFlags flagsToChange) { _proxy.SetFlagsOnAllChannels( value, flagsToChange); }
/// <summary> /// Returns true if the given flags are set for every proxy or if /// the visual is not being marshaled. /// </summary> internal bool CheckFlagsOnAllChannels( VisualProxyFlags conjunctionFlags) { if (_head.Channel != null) { if ((_head.Flags & conjunctionFlags) != conjunctionFlags) return false; for (int i = 0, limit = Count - 1; i < limit; i++) { if ((_tail[i].Flags & conjunctionFlags) != conjunctionFlags) return false; } } return true; }
/// <summary> /// SetFlags is used to set or unset one or multiple flags on a given channel. /// </summary> internal void SetFlags( DUCE.Channel channel, bool value, VisualProxyFlags flagsToChange) { _proxy.SetFlags( channel, value, flagsToChange); }
/// <summary> /// CheckFlagsAnd returns true if all flags in the bitmask flags /// are set on a given channel. /// </summary> /// <remarks> /// If there aren't any bits set on the specified flags /// the method returns true. /// </remarks> internal bool CheckFlagsAnd( DUCE.Channel channel, VisualProxyFlags flagsToCheck) { return (_proxy.GetFlags(channel) & flagsToCheck) == flagsToCheck; }
/// <summary> /// Update EdgeMode /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel"></param> private void UpdateRenderOptions(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { if (((flags & VisualProxyFlags.IsEdgeModeDirty) != 0) || ((flags & VisualProxyFlags.IsBitmapScalingModeDirty) != 0) || ((flags & VisualProxyFlags.IsClearTypeHintDirty) != 0) || ((flags & VisualProxyFlags.IsTextRenderingModeDirty) != 0) || ((flags & VisualProxyFlags.IsTextHintingModeDirty) != 0)) { MilRenderOptions renderOptions = new MilRenderOptions(); // EdgeMode ---------------------------------------------------------------------------- // "isOnChannel" (if true) indicates that this Visual was on channel // previous to this update. If this is the case, all changes to the EdgeMode // must be reflected in the composition node. If "isOnChannel" is false it means // that this Visual has just been added to a channel. In this case, we can // skip an EdgeMode update if the EdgeMode is Unspecified, as this is the default // behavior. EdgeMode edgeMode = EdgeModeField.GetValue(this); if (isOnChannel || (edgeMode != EdgeMode.Unspecified)) { renderOptions.Flags |= MilRenderOptionFlags.EdgeMode; renderOptions.EdgeMode = edgeMode; } // ImageScalingMode ---------------------------------------------------------------------------- BitmapScalingMode bitmapScalingMode = BitmapScalingModeField.GetValue(this); if (isOnChannel || (bitmapScalingMode != BitmapScalingMode.Unspecified)) { renderOptions.Flags |= MilRenderOptionFlags.BitmapScalingMode; renderOptions.BitmapScalingMode = bitmapScalingMode; } ClearTypeHint clearTypeHint = ClearTypeHintField.GetValue(this); if (isOnChannel || (clearTypeHint != ClearTypeHint.Auto)) { renderOptions.Flags |= MilRenderOptionFlags.ClearTypeHint; renderOptions.ClearTypeHint = clearTypeHint; } TextRenderingMode textRenderingMode = TextRenderingModeField.GetValue(this); if (isOnChannel || (textRenderingMode != TextRenderingMode.Auto)) { renderOptions.Flags |= MilRenderOptionFlags.TextRenderingMode; renderOptions.TextRenderingMode = textRenderingMode; } TextHintingMode textHintingMode = TextHintingModeField.GetValue(this); if (isOnChannel || (textHintingMode != TextHintingMode.Auto)) { renderOptions.Flags |= MilRenderOptionFlags.TextHintingMode; renderOptions.TextHintingMode = textHintingMode; } if (renderOptions.Flags != 0) { DUCE.CompositionNode.SetRenderOptions( handle, renderOptions, channel); } SetFlags( channel, false, VisualProxyFlags.IsEdgeModeDirty | VisualProxyFlags.IsBitmapScalingModeDirty | VisualProxyFlags.IsClearTypeHintDirty | VisualProxyFlags.IsTextRenderingModeDirty | VisualProxyFlags.IsTextHintingModeDirty ); } }
/// <summary> /// Propagates the flags up to the root. /// </summary> /// <remarks> /// The walk stops on a node with all of the required flags set. /// </remarks> internal static void PropagateFlags( Visual3D e, VisualFlags flags, VisualProxyFlags proxyFlags) { while ((e != null) && (!e.CheckFlagsAnd(flags) || !e.CheckFlagsOnAllChannels(proxyFlags))) { // These asserts are mostly for documentation when diffing the 2D/3D // implementations. Debug.Assert(!e.CheckFlagsOr(VisualFlags.ShouldPostRender), "Visual3Ds should never be the root of a tree."); Debug.Assert(!e.CheckFlagsOr(VisualFlags.NodeIsCyclicBrushRoot), "Visual3Ds should never be the root of an ICyclicBrush."); e.SetFlags(true, flags); e.SetFlagsOnAllChannels(true, proxyFlags); // If our 3D parent is null call back into VisualTreeUtils to potentially // continue the walk in 2D. if (e._3DParent == null) { Viewport3DVisual viewport = e.InternalVisualParent as Viewport3DVisual; Debug.Assert((viewport == null) == (e.InternalVisualParent == null), "Viewport3DVisual is the only supported 2D parent of a 3D visual."); if(viewport != null) { // We must notify the 2D visual that its contents have changed. // This will cause the 2D visual to set it's content dirty flag // and continue the propagation of IsDirtyForRender/Precompute. viewport.Visual3DTreeChanged(); // continue propagating flags up the 2D world Visual.PropagateFlags(viewport, flags, proxyFlags); } // Stop propagating. We are at the root of the 3D subtree. return; } e = e._3DParent; } }
/// <summary> /// Update content /// </summary> /// <param name="ctx"></param> /// <param name="flags"></param> /// <param name="isOnChannel">The Visual exists on channel.</param> private void UpdateContent(RenderContext ctx, VisualProxyFlags flags, bool isOnChannel) { // // Hookup content to the Visual // if ((flags & VisualProxyFlags.IsContentDirty) != 0) { RenderContent(ctx, isOnChannel); SetFlags(ctx.Channel, false, VisualProxyFlags.IsContentDirty); } }
/// <summary> /// Update offset /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel"></param> private void UpdateOffset(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { // Offset -------------------------------------------------------------------------------------------- if ((flags & VisualProxyFlags.IsOffsetDirty) != 0) { if (isOnChannel || _offset != new Vector()) { // // Offset is (0, 0) by default so do not update it for new visuals. // DUCE.CompositionNode.SetOffset( handle, _offset.X, _offset.Y, channel); } SetFlags(channel, false, VisualProxyFlags.IsOffsetDirty); } }
internal override void RenderContent(RenderContext ctx, bool isOnChannel) { DUCE.Channel channel = ctx.Channel; // // At this point, the visual has to be marshalled. Force // marshalling of the camera and viewport in case we have // just created a new visual resource. // Debug.Assert(IsOnChannel(channel)); VisualProxyFlags flags = _proxy.GetFlags(channel); // // Make sure the camera resource is being marshalled properly. // if ((flags & VisualProxyFlags.Viewport3DVisual_IsCameraDirty) != 0) { Camera camera = Camera; if (camera != null) { DUCE.Viewport3DVisualNode.SetCamera( ((DUCE.IResource) this).GetHandle(channel), ((DUCE.IResource)camera).AddRefOnChannel(channel), channel); } else if (isOnChannel) /* camera == null */ { DUCE.Viewport3DVisualNode.SetCamera( ((DUCE.IResource) this).GetHandle(channel), DUCE.ResourceHandle.Null, channel); } SetFlags(channel, false, VisualProxyFlags.Viewport3DVisual_IsCameraDirty); } // // Set the viewport if it's dirty. // if ((flags & VisualProxyFlags.Viewport3DVisual_IsViewportDirty) != 0) { DUCE.Viewport3DVisualNode.SetViewport( ((DUCE.IResource) this).GetHandle(channel), Viewport, channel); SetFlags(channel, false, VisualProxyFlags.Viewport3DVisual_IsViewportDirty); } //we only want to recurse in the children if the visual does not have a bitmap effect //or we are in the BitmapVisualManager render pass // Visit children of this node ----------------------------------------------------------------------- Debug.Assert(!CheckFlagsAnd(channel, VisualProxyFlags.IsContentNodeConnected), "Only HostVisuals are expected to have a content node."); if (_children != null) { for (uint i = 0; i < _children.InternalCount; i++) { Visual3D child = _children.InternalGetItem((int)i); if (child != null) { if (child.CheckFlagsAnd(channel, VisualProxyFlags.IsSubtreeDirtyForRender) || // or the visual is dirty !(child.IsOnChannel(channel))) // or the child has not been marshalled yet. { child.RenderRecursive(ctx); } if (child.IsOnChannel(channel)) { if (!child.CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent)) { DUCE.Visual3DNode.InsertChildAt( _proxy3D.GetHandle(channel), ((DUCE.IResource)child).GetHandle(channel), /* iPosition = */ i, channel); child.SetFlags(channel, true, VisualProxyFlags.IsConnectedToParent); } } } } } }
/// <summary> /// Update guidelines /// </summary> /// <param name="channel"></param> /// <param name="handle"></param> /// <param name="flags"></param> /// <param name="isOnChannel"></param> private void UpdateGuidelines(DUCE.Channel channel, DUCE.ResourceHandle handle, VisualProxyFlags flags, bool isOnChannel) { // Guidelines -------------------------------------------------------------------- if ((flags & VisualProxyFlags.IsGuidelineCollectionDirty) != 0) { DoubleCollection guidelinesX = GuidelinesXField.GetValue(this); DoubleCollection guidelinesY = GuidelinesYField.GetValue(this); if (isOnChannel || (guidelinesX != null || guidelinesY != null)) { // // Guidelines are null by default, so do not update them for new visuals. // DUCE.CompositionNode.SetGuidelineCollection( handle, guidelinesX, guidelinesY, channel); } SetFlags(channel, false, VisualProxyFlags.IsGuidelineCollectionDirty); } }