Beispiel #1
0
        protected void UpdateTarget(object value)
        {
            // We're called multiple times, for example when a resource dictionary changes.
            // To avoid too many updates, we remember the last updated value.
            if (ReferenceEquals(value, _lastUpdateValue))
            {
                return;
            }
            _lastUpdateValue = value;

            object assignValue = MpfCopyManager.DeepCopyCutLVPs(value);

            if (assignValue is DependencyObject && _targetDataDescriptor.TargetObject is DependencyObject)
            {
                ((DependencyObject)assignValue).LogicalParent = (DependencyObject)_targetDataDescriptor.TargetObject;
            }
#if DEBUG_DRME
            DebugOutput("Setting target value to '{0}'", assignValue);
#endif
            object assignValueConverted = TypeConverter.Convert(assignValue, _targetDataDescriptor.DataType);
            if (!ReferenceEquals(assignValue, assignValueConverted) && !ReferenceEquals(assignValue, value))
            {
                MPF.TryCleanupAndDispose(assignValue);
            }
            _contextObject.SetBindingValue(_targetDataDescriptor, assignValueConverted);
            // If we cannot find any UI element to pass the bindings to, we don't activate them. This means bindings, which are bound to
            // an object which doesn't have an UI element in its logical tree, cannot be activated.
        }
        protected override FrameworkElement PrepareItemContainer(object dataItem)
        {
// ReSharper disable UseObjectOrCollectionInitializer
            TreeViewItem container = new TreeViewItem
// ReSharper restore UseObjectOrCollectionInitializer
            {
                Content       = dataItem,
                Context       = dataItem,
                ForceExpander = ForceExpander,
                Screen        = Screen,
                ElementState  = _elementState,
                LogicalParent = this,
            };

            // Set this after the other properties have been initialized to avoid duplicate work
            container.Style           = MpfCopyManager.DeepCopyCutLVPs(ItemContainerStyle);
            container.ContentTemplate = MpfCopyManager.DeepCopyCutLVPs(ItemTemplate);

            // Re-use some properties for our children
            container.ItemContainerStyle = MpfCopyManager.DeepCopyCutLVPs(ItemContainerStyle);
            container.ItemsPanel         = MpfCopyManager.DeepCopyCutLVPs(ItemsPanel);
            container.ItemTemplate       = MpfCopyManager.DeepCopyCutLVPs(ItemTemplate);
            container.SubItemsProvider   = MpfCopyManager.DeepCopyCutLVPs(SubItemsProvider);
            return(container);
        }
        public static object FindResourceInParserContext(object resourceKey, IParserContext context)
        {
            object result = null;

            // Step up the parser's context stack to find the resource.
            // The logical tree is not yet defined at the load time of the
            // XAML file. This is the reason why we have to step up the parser's context
            // stack. We will have to simulate the process of finding a resource
            // which is normally done by UIElement.FindResource(string).
            // The parser's context stack maintains a dictionary of current keyed
            // elements for each stack level because the according resource
            // dictionaries are not built yet.
            foreach (ElementContextInfo current in context.ContextStack)
            {
                if (current.TryGetKeyedElement(resourceKey, out result) ||
                    // Don't call UIElement.FindResource here, because the logical tree
                    // may be not set up yet.
                    (current.Instance is UIElement && ((UIElement)current.Instance).Resources.TryGetValue(resourceKey, out result)) ||
                    (current.Instance is ResourceDictionary && ((ResourceDictionary)current.Instance).TryGetValue(resourceKey, out result)))
                {
                    break;
                }
            }
            if (result == null)
            {
                return(null);
            }
            // We do a copy of the result to avoid later problems when the property where the result is assigned to is copied.
            // If we don't cut the result's logical parent, a deep copy of the here assigned property would still reference
            // the static resource's logical parent, which would copy an unnecessary big tree.
            // And we cannot simply clean the logical parent of the here found resource because we must not change it.
            // So we must do a copy where we cut the logical parent.
            return(MpfCopyManager.DeepCopyCutLVPs(result));
        }
        internal void OnContentChanged(AbstractProperty prop, object oldValue)
        {
            object content = Content;

            MPF.TryCleanupAndDispose(oldValue);
            if (!ReferenceEquals(oldValue, _convertedContent))
            {
                MPF.TryCleanupAndDispose(_convertedContent);
            }

            object convertedContent;

            // Try to unwrap ResourceWrapper before _convertedContent is accessed elsewhere.
            // That's the only function we need from the ConvertType method, that's why we only call MPF.ConvertType
            // instead of TypeConverter.Convert.
            if (!MPF.ConvertType(content, typeof(object), out convertedContent))
            {
                convertedContent = content;
            }

            _convertedContent = ReferenceEquals(content, convertedContent) ? MpfCopyManager.DeepCopySetLVPs(convertedContent, this, this) : convertedContent;

            if (ContentTemplate == null)
            {
                // No ContentTemplate set
                InstallAutomaticContentDataTemplate();
            }
            FrameworkElement templateControl = _templateControl;

            if (!(_convertedContent is FrameworkElement) && templateControl != null) // If our content is a FrameworkElement itself, it should only be used as template control but not as context
            // The controls in the DataTemplate access their "data" via their data context, so we must assign it
            {
                templateControl.Context = _convertedContent;
            }
        }
        protected void InitializeContentPresenter()
        {
            if (!_contentPresenterInvalid)
            {
                return;
            }
            if (!PreparingOrRunning)
            {
                return;
            }
            object content = Content;

            if (content == null)
            {
                // In default skin, we have the constellation that a Button is used as template control inside a ListViewItem;
                // thus the Button's ContentPresenter gets used twice: First as presenter for the Button's Content (which is null in that case)
                // and second as presenter for the ListViewItem's Content (which is the actual content to be set).
                // If we don't ensure that content != null, the Button resets it's ContentPresenter's Content to null
                return;
            }
            ContentPresenter presenter = FindContentPresenter();

            if (presenter == null)
            {
                return;
            }
            _contentPresenterInvalid             = false;
            presenter.HorizontalContentAlignment = HorizontalContentAlignment;
            presenter.VerticalContentAlignment   = VerticalContentAlignment;
            presenter.ContentTemplate            = MpfCopyManager.DeepCopyCutLVPs(ContentTemplate); // Setting LogicalParent is not necessary because DataTemplate doesn't bind bindings
            presenter.Content = MpfCopyManager.DeepCopyCutLVPs(content);
        }
Beispiel #6
0
        public IBinding CopyAndRetarget(IDataDescriptor newDd)
        {
            IDictionary <object, object> exceptionalIdentities = new Dictionary <object, object>
            {
                { LogicalParent, null }
            };

            if (_contextObject != null)
            {
                exceptionalIdentities.Add(_contextObject, newDd.TargetObject);
            }
            IDataDescriptor targetSave = _targetDataDescriptor;

            try
            {
                _targetDataDescriptor = null; // We have to detach temporarily, else the copy won't work
                BindingBase result = MpfCopyManager.DeepCopyWithIdentities(this, exceptionalIdentities);
                result.SetTargetDataDescriptor(newDd);
                return(result);
            }
            finally
            {
                // Restore this binding attachment
                _targetDataDescriptor = targetSave;
            }
        }
Beispiel #7
0
        public void UpdateTarget()
        {
            object convertedValue;

            if (!Convert(_sourceDd.Value, _targetDd.DataType, out convertedValue))
            {
                return;
            }
            if (ReferenceEquals(_sourceDd.Value, convertedValue))
            {
                convertedValue = MpfCopyManager.DeepCopyCutLVPs(convertedValue);
            }
            if (_targetObject != null)
            {
                _targetObject.SetBindingValue(_targetDd, convertedValue);
            }
            else
            {
                _targetDd.Value = convertedValue;
            }
            if (_notifyOnTargetUpdated && _parentUiElement != null)
            {
                _parentUiElement.RaiseEvent(new DataTransferEventArgs(BindingExtension.TargetUpdatedEvent, _parentUiElement, _targetDd));
            }
        }
Beispiel #8
0
        private void SetTimeIndicator()
        {
            if (_timeIndicatorControl == null)
            {
                _timeIndicatorControl = new Control {
                    LogicalParent = this
                };
                // Deep copy the styles to each program button.
                _timeIndicatorControl.Template = MpfCopyManager.DeepCopyCutLVPs(TimeIndicatorTemplate);
                SetRow(_timeIndicatorControl, 0);
                SetRowSpan(_timeIndicatorControl, _numberOfRows);
                Children.Add(_timeIndicatorControl);
            }
            DateTime viewportStart     = SlimTvMultiChannelGuideModel.GuideStartTime;
            int      currentTimeColumn = (int)Math.Round((DateTime.Now - viewportStart).TotalMinutes / _perCellTime) + 1; // Header offset

            if (currentTimeColumn <= 1 || currentTimeColumn > _numberOfColumns + 1)                                       // Outside viewport
            {
                _timeIndicatorControl.IsVisible = false;
            }
            else
            {
                _timeIndicatorControl.IsVisible = true;
                SetZIndex(_timeIndicatorControl, 100);
                SetColumn(_timeIndicatorControl, currentTimeColumn);
                _timeIndicatorControl.InvalidateLayout(true, true); // Required to arrange control on new position
            }
        }
        protected void InitializeContentPresenter()
        {
            ContentPresenter presenter = FindContentPresenter();

            if (presenter != null)
            {
                presenter.ContentTemplate = MpfCopyManager.DeepCopyCutLVPs(ContentTemplate);
            }
        }
Beispiel #10
0
        private void CreateGroupButton()
        {
            Control btnGroup = CreateControl(null);

            SetGrid(btnGroup, 0, 0, 1, _numberOfRows);

            // Deep copy the styles to each program button.
            btnGroup.Template = MpfCopyManager.DeepCopyCutLVPs(GroupButtonTemplate);
            Children.Add(btnGroup);
        }
        protected object FindResourceInTheme(string resourceKey, IParserContext context)
        {
            object result = SkinContext.SkinResources.FindStyleResource(resourceKey);

            if (result == null)
            {
                return(null);
            }
            // See comment about the copying in method ResourceDictionary.FindResourceInParserContext()
            return(MpfCopyManager.DeepCopyCutLVPs(result));
        }
Beispiel #12
0
        /// <summary>
        /// Tries to find an existing control for given <paramref name="program"/> in the Grid row with index <paramref name="rowIndex"/>.
        /// If no control was found, this method creates a new control and adds it to the Grid.
        /// </summary>
        /// <param name="program">Program.</param>
        /// <param name="rowIndex">RowIndex.</param>
        /// <returns>Control.</returns>
        private Control GetOrCreateControl(ProgramListItem program, int rowIndex)
        {
            Control control = GetRowItems(rowIndex).FirstOrDefault(el => ((ProgramListItem)el.Context).Program.ProgramId == program.Program.ProgramId);

            if (control != null)
            {
                return(control);
            }

            control = CreateControl(program);
            // Deep copy the styles to each program button.
            control.Template = MpfCopyManager.DeepCopyCutLVPs(ProgramTemplate);
            Children.Add(control);
            return(control);
        }
 public UIElement LoadContent()
 {
   if (_templateElement == null)
     return null;
   MpfCopyManager cm = new MpfCopyManager();
   cm.AddIdentity(this, null);
   FrameworkElement result = cm.GetCopy(_templateElement);
   NameScope ns =  (NameScope) cm.GetCopy(_templateElement.TemplateNameScope);
   result.Resources.Merge(Resources);
   if (_names != null)
     foreach (KeyValuePair<string, object> nameRegistration in _names)
       ns.RegisterName(nameRegistration.Key, cm.GetCopy(nameRegistration.Value));
   cm.FinishCopy();
   return result;
 }
        /// <summary>
        /// Will be called to evaluate our source value based on all available
        /// property and context states.
        /// This method will also be automatically re-called when any object involved in the
        /// evaluation process of our source value was changed.
        /// </summary>
        /// <returns><c>true</c>, if the source value based on all input data
        /// could be evaluated, else <c>false</c>.</returns>
        protected bool UpdateSourceValue()
        {
            if (_isUpdatingSourceValue)
            {
                return(false);
            }
            _isUpdatingSourceValue = true;
            bool sourceValueValid = false;

            try
            {
                object result;
                bool   copy = false;
                lock (_syncObj)
                {
                    IDataDescriptor[] values;
                    if (!GetSourceValues(out values))
                    {
                        // Do nothing if not all necessary child bindings can be resolved at the current time
                        return(false);
                    }
                    if (_converter == null)
                    {
                        throw new XamlBindingException("MultiBindingMarkupExtension: Converter must be set");
                    }
                    Type targetType = _targetDataDescriptor == null ? typeof(object) : _targetDataDescriptor.DataType;
                    if (!_converter.Convert(values, targetType, ConverterParameter, out result))
                    {
                        return(false);
                    }
                    copy = values.Any(dd => dd != null && ReferenceEquals(dd.Value, result));
                    IsSourceValueValid = sourceValueValid = true;
                }
                object oldValue = _evaluatedSourceValue.SourceValue;
                // Set the binding's value outside the lock to comply with the MP2 threading policy
                _evaluatedSourceValue.SourceValue = new ValueDataDescriptor(copy ? MpfCopyManager.DeepCopyCutLVPs(result) : result);
                if (oldValue != null)
                {
                    MPF.TryCleanupAndDispose(oldValue);
                }
                return(true);
            }
            finally
            {
                IsSourceValueValid     = sourceValueValid;
                _isUpdatingSourceValue = false;
            }
        }
Beispiel #15
0
        public override void Set(UIElement element)
        {
            IDataDescriptor  dd;
            DependencyObject targetObject;

            if (!FindPropertyDescriptor(element, out dd, out targetObject))
            {
                return;
            }
            SetterData setterData = GetSetterData(targetObject);

            if (setterData != null)
            {
                // If any setter is currently setting our property, we don't want to interfere
                return;
            }
            object obj;

            // The next lines are necessary because the render thread is setting our values.
            // If there's still a value pending to be set by the render thread, we would get an old, obsolete value if
            // we just copied dd.Value to _originalValue.
            element.GetPendingOrCurrentValue(dd, out obj);
            SetSetterData(targetObject, new SetterData(obj));

            object value = Value;

            if (TypeConverter.Convert(value, dd.DataType, out obj))
            {
                if (ReferenceEquals(value, obj))
                {
                    SetDataDescriptorValueWithLP(dd, MpfCopyManager.DeepCopyCutLVPs(obj));
                }
                else
                {
                    // Avoid creating a copy twice
                    SetDataDescriptorValueWithLP(dd, obj);
                }
            }
            else
            {
                // Value is not compatible: We cannot execute
                ServiceRegistration.Get <ILogger>().Warn("Setter for property '{0}': Cannot convert value {1} to target type {2}", _propertyName,
                                                         value == null ? "'null'" : ("of type " + value.GetType().Name), dd.DataType.Name);
                return;
            }
        }
Beispiel #16
0
        protected FrameworkElement PrepareGroupHeader(GroupHeaderItem headerItem, FrameworkElement lvParent)
        {
            var result = new ListViewGroupHeader()
            {
                Context       = headerItem,
                Content       = headerItem,
                Screen        = _parent.Screen,
                VisualParent  = lvParent,
                LogicalParent = lvParent
            };

            // Set this after the other properties have been initialized to avoid duplicate work
            // No need to set the LogicalParent because styles and content templates don't bind bindings
            result.Style           = MpfCopyManager.DeepCopyCutLVPs(GroupHeaderContainerStyle);
            result.ContentTemplate = MpfCopyManager.DeepCopyCutLVPs(GroupHeaderTemplate);
            return(result);
        }
Beispiel #17
0
        protected override FrameworkElement PrepareItemContainer(object dataItem)
        {
// ReSharper disable UseObjectOrCollectionInitializer
            ListViewItem container = new ListViewItem
// ReSharper restore UseObjectOrCollectionInitializer
            {
                Context       = dataItem,
                Content       = dataItem,
                Screen        = Screen,
                ElementState  = _elementState,
                LogicalParent = this,
            };

            // Set this after the other properties have been initialized to avoid duplicate work
            container.Style           = MpfCopyManager.DeepCopyCutLVPs(ItemContainerStyle) ?? container.CopyDefaultStyle();
            container.ContentTemplate = MpfCopyManager.DeepCopyCutLVPs(ItemTemplate);
            return(container);
        }
Beispiel #18
0
        protected FrameworkElement PrepareItem(object dataItem, FrameworkElement lvParent)
        {
// ReSharper disable UseObjectOrCollectionInitializer
            ListViewItem result = new ListViewItem
// ReSharper restore UseObjectOrCollectionInitializer
            {
                Context       = dataItem,
                Content       = dataItem,
                Screen        = _parent.Screen,
                VisualParent  = lvParent,
                LogicalParent = lvParent
            };

            // Set this after the other properties have been initialized to avoid duplicate work
            // No need to set the LogicalParent because styles and content templates don't bind bindings
            result.Style           = MpfCopyManager.DeepCopyCutLVPs(ItemContainerStyle);
            result.ContentTemplate = MpfCopyManager.DeepCopyCutLVPs(ItemTemplate);
            return(result);
        }
Beispiel #19
0
 public void Initialize(FrameworkElement parent, IEnumerable <object> itemsSource, Style itemContainerStyle, DataTemplate itemTemplate)
 {
     _parent = parent;
     if (_materializedItems != null)
     {
         DisposeItems();
     }
     _items             = new List <object>(itemsSource);
     _materializedItems = new List <FrameworkElement>(_items.Count);
     for (int i = 0; i < _items.Count; i++)
     {
         _materializedItems.Add(null);
     }
     MPF.TryCleanupAndDispose(_itemContainerStyle);
     MPF.TryCleanupAndDispose(_itemTemplate);
     // No need to set the LogicalParent at styles or data templates because they don't bind bindings
     _itemContainerStyle = MpfCopyManager.DeepCopyCutLVPs(itemContainerStyle);
     _itemTemplate       = MpfCopyManager.DeepCopyCutLVPs(itemTemplate);
 }
 private Visuals.Control CreateControl(int index)
 {
     if (IsReadOnly)
     {
         return(new Star
         {
             /*Star*/
             Template = MpfCopyManager.DeepCopyCutLVPs(StarReadOnlyTemplate),
             Focusable = false
         });
     }
     else
     {
         return(new CheckBox
         {
             Template = MpfCopyManager.DeepCopyCutLVPs(StarTemplate),
             Checked = new CommandBridge(new MethodDelegateCommand(() => Toggle(index, true))),
             Unchecked = new CommandBridge(new MethodDelegateCommand(() => Toggle(index, false)))
         });
     }
 }
        public void UpdateTarget()
        {
            object convertedValue;

            if (!Convert(_sourceDd.Value, _targetDd.DataType, out convertedValue))
            {
                return;
            }
            if (ReferenceEquals(_sourceDd.Value, convertedValue))
            {
                convertedValue = MpfCopyManager.DeepCopyCutLVPs(convertedValue);
            }
            if (_targetObject != null)
            {
                _targetObject.SetBindingValue(_targetDd, convertedValue);
            }
            else
            {
                _targetDd.Value = convertedValue;
            }
        }
Beispiel #22
0
        private HeaderItemWrapper GetGroupHeader(int itemIndex)
        {
            var headerWrapper = _materializedGroupHeaders[itemIndex];

            if (headerWrapper != null)
            {
                return(headerWrapper);
            }

            if (_groupingValueProvider != null)
            {
                headerWrapper = new HeaderItemWrapper(_groupingValueProvider.GetGroupingValue(_items[itemIndex]));
            }
            else
            {
                // to get the grouping value of the item we use a dummy header item and apply the DataContext and group value binding to it
                if (_getValueGroupHeader == null)
                {
                    _getValueGroupHeader = new GroupHeaderItem();
                    var dd      = new SimplePropertyDataDescriptor(_getValueGroupHeader, typeof(GroupHeaderItem).GetProperty("GroupingValue"));
                    var binding = MpfCopyManager.DeepCopyCutLVPs(_groupPropertyBinding);
                    binding.SetTargetDataDescriptor(dd);
                    binding.Activate();
                }

                _getValueGroupHeader.DataContext = new BindingExtension()
                {
                    Source = _items[itemIndex],
                    Path   = "."
                };
                // then we create the actual header item and apply the value to it
                headerWrapper = new HeaderItemWrapper(_getValueGroupHeader.GroupingValue);

                // finally cleanup the datacontext binding
                MPF.TryCleanupAndDispose(_getValueGroupHeader.DataContext);
                _getValueGroupHeader.DataContext = null;
            }
            _materializedGroupHeaders[itemIndex] = headerWrapper;
            return(headerWrapper);
        }
Beispiel #23
0
 /// <summary>
 /// Worker method to apply all setters on the specified <paramref name="element"/> which
 /// have not been set yet. The set of properties already assigned will be given in parameter
 /// <paramref name="finishedProperties"/>; all properties whose names are stored in this
 /// parameter will be skipped.
 /// </summary>
 /// <param name="element">The UI element this style will be applied on.</param>
 /// <param name="finishedProperties">Set of property names which should be skipped.</param>
 /// <param name="triggers">Returns a collection of triggers which should be added to the <paramref name="element"/>.</param>
 protected void UpdateSettersAndCollectTriggers(UIElement element,
                                                ICollection <string> finishedProperties, ICollection <TriggerBase> triggers)
 {
     foreach (SetterBase sb in _setters)
     {
         string propertyKey = sb.UnambiguousPropertyName;
         if (finishedProperties.Contains(propertyKey))
         {
             continue;
         }
         finishedProperties.Add(propertyKey);
         sb.Set(element);
     }
     if (_basedOn != null)
     {
         _basedOn.UpdateSettersAndCollectTriggers(element, finishedProperties, triggers);
     }
     foreach (TriggerBase trigger in Triggers)
     {
         triggers.Add(MpfCopyManager.DeepCopySetLVPs(trigger, element, null));
     }
 }
        public UIElement LoadContent()
        {
            if (_templateElement == null)
            {
                return(null);
            }
            MpfCopyManager cm = new MpfCopyManager();

            cm.AddIdentity(this, null);
            FrameworkElement result = cm.GetCopy(_templateElement);
            NameScope        ns     = (NameScope)cm.GetCopy(_templateElement.TemplateNameScope);

            result.Resources.Merge(Resources);
            if (_names != null)
            {
                foreach (KeyValuePair <string, object> nameRegistration in _names)
                {
                    ns.RegisterName(nameRegistration.Key, cm.GetCopy(nameRegistration.Value));
                }
            }
            cm.FinishCopy();
            return(result);
        }
Beispiel #25
0
        public UIElement LoadContent(UIElement triggerParent)
        {
            if (_templateElement == null)
            {
                return(null);
            }
            MpfCopyManager cm = new MpfCopyManager();

            cm.AddIdentity(this, null);
            FrameworkElement result = cm.GetCopy(_templateElement);
            NameScope        ns     = (NameScope)cm.GetCopy(_templateElement.TemplateNameScope);

            result.Resources.Merge(Resources);
            if (_names != null)
            {
                foreach (KeyValuePair <string, object> nameRegistration in _names)
                {
                    ns.RegisterName(nameRegistration.Key, cm.GetCopy(nameRegistration.Value));
                }
            }
            triggerParent.UninitializeTriggers();
            ICollection <TriggerBase> triggers = triggerParent.Triggers;

            foreach (TriggerBase t in Triggers)
            {
                TriggerBase trigger = cm.GetCopy(t);
                triggers.Add(trigger);
                // Trigger will automatically be set-up (_initializeTriggers is initially set to true in result)
            }
            cm.FinishCopy();
            // Setting the logical parent has to be done after the copy process has finished - else the logical parent will be overridden
            foreach (TriggerBase t in triggers)
            {
                t.LogicalParent = result;
            }
            return(result);
        }
Beispiel #26
0
        public void Initialize(FrameworkElement parent, IEnumerable <object> itemsSource, Style itemContainerStyle, DataTemplate itemTemplate,
                               IGroupingValueProvider groupingValueProvider, IBinding groupPropertyBinding, Style groupHeaderContainerStyle, DataTemplate groupHeaderTemplate)
        {
            _parent = parent;

            DisposeItems();
            _items             = new List <object>(itemsSource);
            _materializedItems = new List <FrameworkElement>(_items.Count);
            for (int i = 0; i < _items.Count; i++)
            {
                _materializedItems.Add(null);
            }
            _groupInfos = null;

            if ((groupingValueProvider != null && groupingValueProvider.IsGroupingActive) || groupPropertyBinding != null)
            {
                _materializedGroupHeaders = new HeaderItemWrapper[_items.Count];
            }

            MPF.TryCleanupAndDispose(_itemContainerStyle);
            MPF.TryCleanupAndDispose(_itemTemplate);
            // No need to set the LogicalParent at styles or data templates because they don't bind bindings
            _itemContainerStyle = MpfCopyManager.DeepCopyCutLVPs(itemContainerStyle);
            _itemTemplate       = MpfCopyManager.DeepCopyCutLVPs(itemTemplate);

            MPF.TryCleanupAndDispose(_groupHeaderContainerStyle);
            MPF.TryCleanupAndDispose(_groupHeaderTemplate);
            MPF.TryCleanupAndDispose(_groupPropertyBinding);
            _groupingValueProvider     = groupingValueProvider;
            _groupPropertyBinding      = MpfCopyManager.DeepCopyCutLVPs(groupPropertyBinding);
            _groupHeaderContainerStyle = MpfCopyManager.DeepCopyCutLVPs(groupHeaderContainerStyle);
            _groupHeaderTemplate       = MpfCopyManager.DeepCopyCutLVPs(groupHeaderTemplate);

            MPF.TryCleanupAndDispose(_getValueGroupHeader);
            _getValueGroupHeader = null;
        }
 public UIElement LoadContent(UIElement triggerParent)
 {
   if (_templateElement == null)
     return null;
   MpfCopyManager cm = new MpfCopyManager();
   cm.AddIdentity(this, null);
   FrameworkElement result = cm.GetCopy(_templateElement);
   NameScope ns =  (NameScope) cm.GetCopy(_templateElement.TemplateNameScope);
   result.Resources.Merge(Resources);
   if (_names != null)
     foreach (KeyValuePair<string, object> nameRegistration in _names)
       ns.RegisterName(nameRegistration.Key, cm.GetCopy(nameRegistration.Value));
   triggerParent.UninitializeTriggers();
   ICollection<TriggerBase> triggers = triggerParent.Triggers;
   foreach (TriggerBase t in Triggers)
   {
     TriggerBase trigger = cm.GetCopy(t);
     triggers.Add(trigger);
     // Trigger will automatically be set-up (_initializeTriggers is initially set to true in result)
   }
   cm.FinishCopy();
   // Setting the logical parent has to be done after the copy process has finished - else the logical parent will be overridden
   foreach (TriggerBase t in triggers)
     t.LogicalParent = result;
   return result;
 }
Beispiel #28
0
        protected virtual void PrepareItemsOverride(bool force)
        {
            if (_panelTemplateApplied && _itemsHostPanel != null && !force)
            {
                return;
            }
            // Check properties which are necessary in each case
            if (ItemsPanel == null)
            {
                return;
            }

            ItemsPresenter presenter = FindItemsPresenter();

            if (presenter == null)
            {
                return;
            }

            if (!_panelTemplateApplied)
            {
                _panelTemplateApplied = true;
                presenter.ApplyTemplate(ItemsPanel);
                _itemsHostPanel = null;
            }

            if (_itemsHostPanel == null)
            {
                _itemsHostPanel = presenter.ItemsHostPanel;
            }
            if (_itemsHostPanel == null)
            {
                return;
            }

            // Albert: We cannot exit the method if one of the styles is not set because the styles
            // might be found by the SkinEngine's automatic Style assignment (FrameworkElement.CopyDefaultStyle)
            //if (ItemContainerStyle == null || ItemTemplate == null)
            //  return;

            IEnumerable itemsSource = ItemsSource;

            if (itemsSource == null)
            { // In this case, we must set up the items control using the Items property
                ItemCollection items            = _items;
                ItemCollection preparedChildren = new ItemCollection();
                bool           setItems         = false;
                if (items == null)
                {
                    // Restore items from "ItemsSource mode" where they have been set to null
                    items    = new ItemCollection();
                    setItems = true;
                }
                foreach (object item in items)
                {
                    object           itemCopy = MpfCopyManager.DeepCopyWithFixedObject(item, this); // Keep this object as LogicalParent
                    FrameworkElement element  = itemCopy as FrameworkElement ?? PrepareItemContainer(itemCopy);
                    if (element.Style == null && element is ContentControl)
                    {
                        element.Style = ItemContainerStyle;
                    }
                    element.LogicalParent = this;
                    preparedChildren.Add(element);
                }
                presenter.SetDataStrings(BuildDataStrings(items));

                SetPreparedItems(setItems, setItems ? items : null, true, preparedChildren);
            }
            else
            {
                IList <object>  l    = new List <object>();
                ISynchronizable sync = itemsSource as ISynchronizable;
                if (sync != null)
                {
                    lock (sync.SyncRoot)
                        CollectionUtils.AddAll(l, itemsSource);
                }
                else
                {
                    CollectionUtils.AddAll(l, itemsSource);
                }

                presenter.SetDataStrings(BuildDataStrings(l));

                var vsp = _itemsHostPanel as IVirtualizingPanel;
                if (vsp != null)
                {
                    // In this case, the VSP will generate its items by itself
                    ListViewItemGenerator lvig = new ListViewItemGenerator();
                    lvig.Initialize(this, l, ItemContainerStyle, ItemTemplate,
                                    GroupingValueProvider, GroupingBindingWrapper == null ? null :  GroupingBindingWrapper.Binding, GroupHeaderContainerStyle, GroupHeaderTemplate);
                    SimplePropertyDataDescriptor dd;
                    if (SimplePropertyDataDescriptor.CreateSimplePropertyDataDescriptor(this, "IsEmpty", out dd))
                    {
                        SetValueInRenderThread(dd, l.Count == 0);
                    }
                    vsp.SetItemProvider(lvig);

                    SetPreparedItems(true, null, false, null);
                }
                else
                {
                    ItemCollection preparedItems = new ItemCollection();
                    preparedItems.AddAll(l.Select(PrepareItemContainer));

                    SetPreparedItems(true, null, true, preparedItems);
                }
            }
        }
Beispiel #29
0
        protected virtual void PrepareItemsOverride(bool force)
        {
            if (_panelTemplateApplied && _itemsHostPanel != null && !force)
            {
                return;
            }
            // Check properties which are necessary in each case
            if (ItemsPanel == null)
            {
                return;
            }

            ItemsPresenter presenter = FindItemsPresenter();

            if (presenter == null)
            {
                return;
            }

            if (!_panelTemplateApplied)
            {
                _panelTemplateApplied = true;
                presenter.ApplyTemplate(ItemsPanel);
                _itemsHostPanel = null;
            }

            if (_itemsHostPanel == null)
            {
                _itemsHostPanel = presenter.ItemsHostPanel;
            }
            if (_itemsHostPanel == null)
            {
                return;
            }

            IEnumerable itemsSource = ItemsSource;

            if (itemsSource == null)
            { // In this case, we must set up the items control using the Items property
                ItemCollection items            = _items;
                ItemCollection preparedChildren = new ItemCollection();
                bool           setItems         = false;
                if (items == null)
                {
                    // Restore items from "ItemsSource mode" where they have been set to null
                    items    = new ItemCollection();
                    setItems = true;
                }
                foreach (object item in items)
                {
                    object           itemCopy = MpfCopyManager.DeepCopyWithFixedObject(item, this); // Keep this object as LogicalParent
                    FrameworkElement element  = itemCopy as FrameworkElement ?? PrepareItemContainer(itemCopy);
                    if (element.Style == null)
                    {
                        element.Style = ItemContainerStyle;
                    }
                    element.LogicalParent = this;
                    preparedChildren.Add(element);
                }
                presenter.SetDataStrings(BuildDataStrings(items));

                SetPreparedItems(setItems, setItems ? items : null, true, preparedChildren);
            }
            else
            {
                IList <object>  l    = new List <object>();
                ISynchronizable sync = itemsSource as ISynchronizable;
                if (sync != null)
                {
                    lock (sync.SyncRoot)
                        CollectionUtils.AddAll(l, itemsSource);
                }
                else
                {
                    CollectionUtils.AddAll(l, itemsSource);
                }

                presenter.SetDataStrings(BuildDataStrings(l));

                VirtualizingStackPanel vsp = _itemsHostPanel as VirtualizingStackPanel;
                if (vsp != null)
                {
                    // In this case, the VSP will generate its items by itself
                    ListViewItemGenerator lvig = new ListViewItemGenerator();
                    lvig.Initialize(this, l, ItemContainerStyle, ItemTemplate);
                    IsEmpty = l.Count == 0;
                    vsp.SetItemProvider(lvig);

                    SetPreparedItems(true, null, false, null);
                }
                else
                {
                    ItemCollection preparedItems = new ItemCollection();
                    preparedItems.AddAll(l.Select(PrepareItemContainer));

                    SetPreparedItems(true, null, true, preparedItems);
                }
            }
        }
Beispiel #30
0
        private bool CreateOrUpdateRow(bool updateOnly, ref int channelIndex, int rowIndex)
        {
            if (channelIndex >= ChannelsPrograms.Count)
            {
                return(false);
            }
            ChannelProgramListItem channel = ChannelsPrograms[channelIndex] as ChannelProgramListItem;

            if (channel == null)
            {
                return(false);
            }

            // Default: take viewport from model
            var model = SlimTvMultiChannelGuideModel;

            if (model == null)
            {
                return(false);
            }
            DateTime viewportStart = model.GuideStartTime;
            DateTime viewportEnd   = model.GuideEndTime;

            int colIndex = GroupButtonEnabled ? 1 : 0;

            if (!updateOnly)
            {
                Control btnHeader = CreateControl(channel);
                SetGrid(btnHeader, colIndex, rowIndex, 1);

                // Deep copy the styles to each program button.
                btnHeader.Template = MpfCopyManager.DeepCopyCutLVPs(HeaderTemplate);
                Children.Add(btnHeader);
            }

            int      colSpan       = 0;
            DateTime?lastStartTime = null;
            DateTime?lastEndTime   = viewportStart;

#if DEBUG_LAYOUT
            // Debug layouting:
            if (rowIndex == 0)
            {
                ServiceRegistration.Get <ILogger>().Debug("EPG: Viewport: {0}-{1} PerCell: {2} min", viewportStart.ToShortTimeString(), viewportEnd.ToShortTimeString(), _perCellTime);
            }
#endif
            if (updateOnly)
            {
                // Remove all programs outside of viewport.
                DateTime start      = viewportStart;
                DateTime end        = viewportEnd;
                var      removeList = GetRowItems(rowIndex).Where(el =>
                {
                    ProgramListItem p = (ProgramListItem)el.Context;
                    return(p.Program.EndTime <= start || p.Program.StartTime >= end || channel.Channel.ChannelId != ((IProgram)p.AdditionalProperties["PROGRAM"]).ChannelId ||
                           p is PlaceholderListItem);
                }).ToList();
                removeList.ForEach(Children.Remove);
            }

            colIndex++; // After header (and optional GroupButton)
            int programIndex = 0;
            while (programIndex < channel.Programs.Count && colIndex <= _numberOfColumns)
            {
                ProgramListItem program = channel.Programs[programIndex] as ProgramListItem;
                if (program == null || program.Program.StartTime > viewportEnd)
                {
                    break;
                }

                // Ignore programs outside viewport and programs that start at same time (duplicates)
                if (program.Program.EndTime <= viewportStart || (lastStartTime.HasValue && lastStartTime.Value == program.Program.StartTime))
                {
                    programIndex++;
                    continue;
                }

                lastStartTime = program.Program.StartTime;

                CalculateProgamPosition(program, viewportStart, viewportEnd, ref colIndex, ref colSpan, ref lastEndTime);

                Control btnEpg = GetOrCreateControl(program, rowIndex);
                SetGrid(btnEpg, colIndex, rowIndex, colSpan);
                programIndex++;
                colIndex += colSpan; // Skip spanned columns.
            }
            channelIndex++;
            return(true);
        }
        protected virtual bool UpdateBinding()
        {
            // Avoid recursive calls: For instance, this can occur when
            // the later call to Evaluate will change our evaluated source value, which
            // will cause a recursive call to UpdateBinding.
            if (_isUpdatingBinding)
            {
                return(false);
            }
            _isUpdatingBinding = true;
            try
            {
                if (KeepBinding) // This is the case if our target descriptor has a binding type
                {                // In this case, this instance should be used rather than the evaluated source value
                    if (_targetDataDescriptor != null)
                    {
                        _contextObject.SetBindingValue(_targetDataDescriptor, this);
                    }
                    _valueAssigned = true;
                    return(true);
                }
                IDataDescriptor sourceDd;
                if (!Evaluate(out sourceDd))
                {
                    _valueAssigned = false;
                    return(false);
                }

                // We're called multiple times, for example when a resource dictionary changes.
                // To avoid too many updates, we remember the last updated value.
                if (ReferenceEquals(sourceDd, _lastUpdatedValue) && !_valueAssigned)
                {
                    return(true);
                }
                _lastUpdatedValue = sourceDd;

#if DEBUG_BINDINGS
                DebugOutput("UpdateBinding: Binding evaluated to '{0}'", sourceDd.Value);
#endif

                if (_bindingDependency != null)
                {
                    _bindingDependency.Detach();
                }

                bool attachToSource = false;
                bool attachToTarget = false;
                switch (Mode)
                {
                case BindingMode.Default:
                case BindingMode.OneWay:
                    // Currently, we don't really support the Default binding mode in
                    // MediaPortal skin engine. Maybe we will support it in future -
                    // then we'll be able to initialize the mode with a default value
                    // implied by our target data endpoint.
                    attachToSource = true;
                    break;

                case BindingMode.TwoWay:
                    attachToSource = true;
                    attachToTarget = true;
                    break;

                case BindingMode.OneWayToSource:
                    attachToTarget = true;
                    break;

                case BindingMode.OneTime:
                    object value = sourceDd.Value;
                    object convertedValue;
                    if (!Convert(value, _targetDataDescriptor.DataType, out convertedValue))
                    {
                        return(false);
                    }
                    _contextObject.SetBindingValue(_targetDataDescriptor,
                                                   ReferenceEquals(value, convertedValue) ? MpfCopyManager.DeepCopyCutLVPs(convertedValue) : convertedValue);
                    _valueAssigned = true;
                    Dispose(true);
                    return(true); // In this case, we have finished with only assigning the value
                }
                DependencyObject parent;
                if (UpdateSourceTrigger != UpdateSourceTrigger.LostFocus ||
                    !FindAncestor(_contextObject, out parent, FindParentMode.HybridPreferVisualTree, -1, typeof(UIElement)))
                {
                    parent = null;
                }
                _bindingDependency = new BindingDependency(sourceDd, _targetDataDescriptor, attachToSource,
                                                           attachToTarget ? UpdateSourceTrigger : UpdateSourceTrigger.Explicit,
                                                           parent as UIElement, _valueConverter, _converterParameter);
                _valueAssigned = true;
                return(true);
            }
            finally
            {
                _isUpdatingBinding = false;
            }
        }
 /// <summary>
 /// Merges the resources in the given resource dictionary to this resource dictionary. That means, the given dict
 /// will be copied and then the copy will be used as parameter for <see cref="TakeOver"/>.
 /// instance.
 /// </summary>
 /// <param name="dict">Resource dictionary whose contents should be merged.</param>
 public void Merge(ResourceDictionary dict)
 {
     // No need to set the LogicalParent at the result because we don't bind bindings in ResourceDictionary
     TakeOver(MpfCopyManager.DeepCopyCutLVPs(dict), false, true);
 }