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); }
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; } }
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)); } }
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); } }
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)); }
/// <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; } }
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; } }
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); }
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); }
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); }
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; } }
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); }
/// <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); }
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); }
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; }
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); } } }
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); } } }
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); }