/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
public delegate void resChangeCb(object sender, ResourcesChangedEventArgs e);
- internal event EventHandler<ResourcesChangedEventArgs> XamlResourceChanged;
-
internal override void OnResourcesChanged(object sender, ResourcesChangedEventArgs e)
{
base.OnResourcesChanged(sender, e);
- XamlResourceChanged?.Invoke(sender, e);
}
public ResourceDictionary XamlResources
internal override void OnParentResourcesChanged(IEnumerable<KeyValuePair<string, object>> values)
{
+ if (values == null)
+ return;
+
if (!((IResourcesProvider)this).IsResourcesCreated || XamlResources.Count == 0)
{
base.OnParentResourcesChanged(values);
if (innerKeys.Add(value.Key))
changedResources.Add(value);
}
- OnResourcesChanged(changedResources);
+ if (changedResources.Count != 0)
+ OnResourcesChanged(changedResources);
}
internal Application(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
public bool StopOnResourceDictionary { get; }
public bool VisitNodeOnDataTemplate => true;
public bool SkipChildren(INode node, INode parentNode) => false;
- public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]);
+ public bool IsResourceDictionary(ElementNode node) => Context.Types.TryGetValue(node, out var type) && typeof(ResourceDictionary).IsAssignableFrom(type);
public void Visit(ValueNode node, INode parentNode)
{
var parentElement = parentNode as IElementNode;
var value = Values[node];
- var source = Values[parentNode];
+ if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null)
+ return;
XmlName propertyName;
if (TryGetPropertyName(node, parentNode, out propertyName))
parentElement = parentNode as IElementNode;
}
- var value = Values[node];
+ if (!Values.TryGetValue(node, out var value) && Context.ExceptionHandler != null)
+ return;
if (propertyName != XmlName.Empty || TryGetPropertyName(node, parentNode, out propertyName))
{
if (parentElement.SkipProperties.Contains(propertyName))
return;
- var source = Values[parentNode];
+ if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null)
+ return;
ProvideValue(ref value, node, source, propertyName);
SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node);
}
else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode)
{
- var source = Values[parentNode];
+ if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null)
+ return;
ProvideValue(ref value, node, source, XmlName.Empty);
string contentProperty;
Exception xpe = null;
xpe = xpe ?? new XamlParseException($"Can not set the content of {((IElementNode)parentNode).XmlType.Name} as it doesn't have a ContentPropertyAttribute", node);
if (Context.ExceptionHandler != null)
Context.ExceptionHandler(xpe);
- throw xpe;
+ else
+ throw xpe;
}
else if (IsCollectionItem(node, parentNode) && parentNode is ListNode)
{
- var source = Values[parentNode.Parent];
+ if (!Values.TryGetValue(parentNode.Parent, out var source) && Context.ExceptionHandler != null)
+ return;
ProvideValue(ref value, node, source, XmlName.Empty);
var parentList = (ListNode)parentNode;
if (Skips.Contains(parentList.XmlName))
{
(serviceProvider.IProvideValueTarget as XamlValueTargetProvider).TargetProperty = GetTargetProperty(source, propertyName, Context, node);
}
-
- if (markupExtension != null)
- value = markupExtension.ProvideValue(serviceProvider);
- else if (valueProvider != null)
- value = valueProvider.ProvideValue(serviceProvider);
+ try {
+ if (markupExtension != null)
+ value = markupExtension.ProvideValue(serviceProvider);
+ else if (valueProvider != null)
+ value = valueProvider.ProvideValue(serviceProvider);
+ } catch (Exception e) {
+ if (Context.ExceptionHandler != null)
+ Context.ExceptionHandler(e);
+ else
+ throw;
+ }
}
static string GetContentPropertyName(IEnumerable<CustomAttributeData> attributes)
if (xKey != null)
resourceDictionary.Add(xKey, value);
+ else if (value is XamlStyle)
+ resourceDictionary.Add((XamlStyle)value);
else if (value is ResourceDictionary)
resourceDictionary.Add((ResourceDictionary)value);
else
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
if (value is Element element)
{
- if (null != Application.Current)
- {
- Application.Current.XamlResourceChanged += element.OnResourcesChanged;
- }
-
element.IsCreateByXaml = true;
}
}
object ret = Activator.CreateInstance(nodeType, BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance | BindingFlags.OptionalParamBinding, null, arguments, CultureInfo.CurrentCulture);
if (ret is Element element)
{
- if (null != Application.Current)
- {
- Application.Current.XamlResourceChanged += element.OnResourcesChanged;
- }
-
element.IsCreateByXaml = true;
}
return ret;
value = Activator.CreateInstance(nodeType);
if (value is Element element)
{
- if (null != Application.Current)
- {
- Application.Current.XamlResourceChanged += element.OnResourcesChanged;
- }
-
element.IsCreateByXaml = true;
}
}
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
public void Visit(ValueNode node, INode parentNode)
{
- if (!typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)]))
+ if (!Context.Types.TryGetValue((IElementNode)parentNode, out var type) || !typeof(ResourceDictionary).IsAssignableFrom(type))
return;
node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
public void Visit(ElementNode node, INode parentNode)
{
- var value = Values[node];
+ if (!Values.TryGetValue(node, out var value) && Context.ExceptionHandler != null)
+ return;
XmlName propertyName;
//Set RD to VE
if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]) && ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName))
{
- if ((propertyName.LocalName == "Resources" ||
- propertyName.LocalName.EndsWith(".Resources", StringComparison.Ordinal)) && value is ResourceDictionary)
+ if ((propertyName.LocalName == "XamlResources" ||
+ propertyName.LocalName.EndsWith(".XamlResources", StringComparison.Ordinal)) && value is ResourceDictionary)
{
var source = Values[parentNode];
ApplyPropertiesVisitor.SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node);
//Only proceed further if the node is a keyless RD
if (parentNode is IElementNode
- && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)])
+ && Context.Types.TryGetValue((IElementNode)parentNode, out var parentType)
+ && typeof(ResourceDictionary).IsAssignableFrom(parentType)
&& !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode);
else if (parentNode is ListNode
if (enode is null)
return false;
if (parentNode is IElementNode
- && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)])
+ && Context.Types.TryGetValue((IElementNode)parentNode, out var parentType)
+ && typeof(ResourceDictionary).IsAssignableFrom(parentType)
&& !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey))
return true;
if (parentNode is ListNode
-/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
internal interface IResourcesLoader
{
T CreateFromResource<T>(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo) where T : new();
- string GetResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo);
+ string GetResource(string resourcePath, Assembly assembly, object target, IXmlLineInfo lineInfo);
}
}
-/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
public T CreateFromResource<T>(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo) where T : new()
{
- var alternateResource = ResourceLoader.ResourceProvider?.Invoke(assembly.GetName(), resourcePath);
+ var rd = new T();
+ var resourceLoadingResponse = ResourceLoader.ResourceProvider?.Invoke(new ResourceLoader.ResourceLoadingQuery
+ {
+ AssemblyName = assembly.GetName(),
+ ResourcePath = resourcePath,
+ Instance = rd
+ });
+ var alternateResource = resourceLoadingResponse?.ResourceContent;
if (alternateResource != null)
{
- var rd = new T();
rd.LoadFromXaml(alternateResource);
return rd;
}
throw new XamlParseException($"No resource found for '{resourceId}'.", lineInfo);
using (var reader = new StreamReader(stream))
{
- var rd = new T();
rd.LoadFromXaml(reader.ReadToEnd());
return rd;
}
}
}
- public string GetResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo)
+ public string GetResource(string resourcePath, Assembly assembly, object target, IXmlLineInfo lineInfo)
{
- var alternateResource = ResourceLoader.ResourceProvider?.Invoke(assembly.GetName(), resourcePath);
+ var resourceLoadingResponse = ResourceLoader.ResourceProvider?.Invoke(new ResourceLoader.ResourceLoadingQuery {
+ AssemblyName = assembly.GetName(),
+ ResourcePath = resourcePath,
+ Instance = target
+ });
+ var alternateResource = resourceLoadingResponse?.ResourceContent;
if (alternateResource != null)
return alternateResource;
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), ret, (IXmlNamespaceResolver)reader);
XamlParser.ParseXaml(rootnode, reader);
+ var doNotThrow = ResourceLoader.ExceptionHandler != null || Internals.XamlLoader.DoNotThrowOnExceptions;
+ void ehandler(Exception e) => ResourceLoader.ExceptionHandler?.Invoke((e, path));
Visit(rootnode, new HydrationContext
{
RootElement = ret,
#pragma warning disable 0618
- ExceptionHandler = ResourceLoader.ExceptionHandler ?? (Internals.XamlLoader.DoNotThrowOnExceptions ? e => { } : (Action<Exception>)null)
+ ExceptionHandler = doNotThrow ? ehandler : (Action<Exception>)null
#pragma warning restore 0618
});
break;
var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), view, (IXmlNamespaceResolver)reader);
XamlParser.ParseXaml(rootnode, reader);
+ var doNotThrow = ResourceLoader.ExceptionHandler != null || Internals.XamlLoader.DoNotThrowOnExceptions;
+ void ehandler(Exception e) => ResourceLoader.ExceptionHandler?.Invoke((e, XamlFilePathAttribute.GetFilePathForObject(view)));
Visit(rootnode, new HydrationContext
{
RootElement = view,
#pragma warning disable 0618
- ExceptionHandler = ResourceLoader.ExceptionHandler ?? (Internals.XamlLoader.DoNotThrowOnExceptions ? e => { } : (Action<Exception>)null)
+ ExceptionHandler = doNotThrow ? ehandler : (Action<Exception>)null
#pragma warning restore 0618
});
break;
-/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
{
internal static class ResourceLoader
{
- static Func<AssemblyName, string, string> resourceProvider = (asmName, path) =>
- {
- if (typeof(Theme).Assembly.GetName().FullName != asmName.FullName)
+ static Func<ResourceLoadingQuery, ResourceLoadingResponse> _resourceProvider = (resourceLoadingQuery) => {
+ if (typeof(Theme).Assembly.GetName().FullName != resourceLoadingQuery.AssemblyName.FullName)
{
string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
- path = resource + path;
+ resourceLoadingQuery.ResourcePath = resource + resourceLoadingQuery.ResourcePath;
}
- string ret = File.ReadAllText(path);
- return ret;
+ string ret = File.ReadAllText(resourceLoadingQuery.ResourcePath);
+ return new ResourceLoadingResponse { ResourceContent = ret };
};
-
- //takes a resource path, returns string content
- public static Func<AssemblyName, string, string> ResourceProvider
+ public static Func<ResourceLoadingQuery, ResourceLoadingResponse> ResourceProvider
{
- get => resourceProvider;
+ get => _resourceProvider;
internal set
{
- DesignMode.IsDesignModeEnabled = true;
- resourceProvider = value;
+ DesignMode.IsDesignModeEnabled = value != null;
+ _resourceProvider = value;
}
}
- internal static Action<Exception> ExceptionHandler { get; set; }
+ internal static Action<(Exception exception, string filepath)> ExceptionHandler { get; set; }
+
+ public class ResourceLoadingQuery
+ {
+ public AssemblyName AssemblyName { get; set; }
+ public string ResourcePath { get; set; }
+ public object Instance { get; set; }
+ }
+
+ public class ResourceLoadingResponse
+ {
+ public string ResourceContent { get; set; }
+ public bool UseDesignProperties { get; set; }
+ }
}
}
public IStyle Style
{
get { return style; }
- set { SetStyle(ImplicitStyle, ClassStyles, value); }
+ set
+ {
+ if (style == value)
+ return;
+ if (value != null && !value.TargetType.IsAssignableFrom(TargetType))
+ NUILog.Error($"Style TargetType {value.TargetType.FullName} is not compatible with element target type {TargetType}");
+ SetStyle(ImplicitStyle, ClassStyles, value);
+ }
}
public IList<string> StyleClass
if (styleClass == value)
return;
- if (styleClass != null && classStyles != null)
+ if (styleClass != null && classStyleProperties != null)
foreach (var classStyleProperty in classStyleProperties)
Target.RemoveDynamicResource(classStyleProperty);
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
if (ve.XamlResources != null)
{
foreach (KeyValuePair<string, object> res in ve.XamlResources.MergedResources)
- if (!resources.ContainsKey(res.Key))
- resources.Add(res.Key, res.Value);
+ {
+ // If a MergedDictionary value is overridden for a DynamicResource,
+ // it comes out later in the enumeration of MergedResources
+ // TryGetValue ensures we pull the up-to-date value for the key
+ if (!resources.ContainsKey(res.Key) && ve.XamlResources.TryGetValue(res.Key, out object value))
+ resources.Add(res.Key, value);
+ }
}
}
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
}
- /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public bool IsResourcesCreated
- {
- get
- {
- return Application.Current.IsResourcesCreated;
- }
- }
-
- /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ResourceDictionary XamlResources
- {
- get
- {
- return Application.Current.XamlResources;
- }
- set
- {
- Application.Current.XamlResources = value;
- }
- }
-
/// <summary>
/// The StyleName, type string.
/// The value indicates DALi style name defined in json theme file.
}
}
- [EditorBrowsable(EditorBrowsableState.Never)]
- public XamlStyle XamlStyle
- {
- get
- {
- return (XamlStyle)GetValue(XamlStyleProperty);
- }
- set
- {
- SetValue(XamlStyleProperty, value);
- }
- }
-
/// <summary>
/// The Color of View. This is an RGBA value.
/// </summary>
});
/// <summary>
- /// XamlStyleProperty
- /// </summary>
- [EditorBrowsable(EditorBrowsableState.Never)]
- public static readonly BindableProperty XamlStyleProperty = BindableProperty.Create(nameof(XamlStyle), typeof(XamlStyle), typeof(View), default(XamlStyle), propertyChanged: (bindable, oldvalue, newvalue) => ((View)bindable).MergedStyle.Style = (XamlStyle)newvalue);
-
- /// <summary>
/// EnableControlState property
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
-/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
using System;
-using System.Collections.Generic;
using System.ComponentModel;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using Tizen.NUI.Binding;
namespace Tizen.NUI.BaseComponents
{
/// <since_tizen> 3 </since_tizen>
public partial class View
{
- private MergedStyle mergedStyle = null;
internal string styleName;
- internal MergedStyle MergedStyle
- {
- get
- {
- if (null == mergedStyle)
- {
- mergedStyle = new MergedStyle(GetType(), this);
- }
-
- return mergedStyle;
- }
- }
internal virtual LayoutItem CreateDefaultLayout()
{
return new AbsoluteLayout();
Children.Remove(child);
child.InternalParent = null;
- RemoveChildBindableObject(child);
-
+ OnChildRemoved(child);
if (ChildRemoved != null)
{
ChildRemovedEventArgs e = new ChildRemovedEventArgs
-/*
- * Copyright(c) 2020 Samsung Electronics Co., Ltd.
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
if (NDalicPINVOKE.SWIGPendingException.Pending)
throw NDalicPINVOKE.SWIGPendingException.Retrieve();
Children.Add(child);
+ OnChildAdded(child);
if (ChildAdded != null)
{
};
ChildAdded(this, e);
}
-
- AddChildBindableObject(child);
}
}
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
}
disposed = true;
-
- if (null != Application.Current)
- {
- Application.Current.XamlResourceChanged -= OnResourcesChanged;
- }
}
/// <summary>
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
using System;
using System.Collections.Generic;
+using System.ComponentModel;
using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
namespace Tizen.NUI
{
/// added to them.
/// </summary>
/// <since_tizen> 4 </since_tizen>
- public abstract class Container : Animatable
+ public abstract class Container : Animatable, IResourcesProvider
{
+ /// <summary> XamlStyleProperty </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static readonly BindableProperty XamlStyleProperty = BindableProperty.Create(nameof(XamlStyle), typeof(XamlStyle), typeof(Container), default(XamlStyle), propertyChanged: (bindable, oldvalue, newvalue) => ((View)bindable).MergedStyle.Style = (XamlStyle)newvalue);
+
internal BaseHandle InternalParent;
private List<View> childViews = new List<View>();
+ private MergedStyle mergedStyle = null;
+ ResourceDictionary _resources;
+ bool IResourcesProvider.IsResourcesCreated => _resources != null;
internal Container(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn)
{
// No un-managed data hence no need to store a native ptr
}
+ /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ResourceDictionary XamlResources
+ {
+ get
+ {
+ if (_resources != null)
+ return _resources;
+ _resources = new ResourceDictionary();
+ ((IResourceDictionary)_resources).ValuesChanged += OnResourcesChanged;
+ return _resources;
+ }
+ set
+ {
+ if (_resources == value)
+ return;
+ OnPropertyChanging();
+ if (_resources != null)
+ ((IResourceDictionary)_resources).ValuesChanged -= OnResourcesChanged;
+ _resources = value;
+ OnResourcesChanged(value);
+ if (_resources != null)
+ ((IResourceDictionary)_resources).ValuesChanged += OnResourcesChanged;
+ OnPropertyChanged();
+ }
+ }
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public XamlStyle XamlStyle
+ {
+ get
+ {
+ return (XamlStyle)GetValue(XamlStyleProperty);
+ }
+ set
+ {
+ SetValue(XamlStyleProperty, value);
+ }
+ }
+
+ internal MergedStyle MergedStyle
+ {
+ get
+ {
+ if (null == mergedStyle)
+ {
+ mergedStyle = new MergedStyle(GetType(), this);
+ }
+
+ return mergedStyle;
+ }
+ }
+
/// <summary>
/// List of children of Container.
/// </summary>
public abstract UInt32 GetChildCount();
internal abstract View FindCurrentChildById(uint id);
+
+ internal override void OnParentResourcesChanged(IEnumerable<KeyValuePair<string, object>> values)
+ {
+ if (values == null)
+ return;
+
+ if (!((IResourcesProvider)this).IsResourcesCreated || XamlResources.Count == 0)
+ {
+ base.OnParentResourcesChanged(values);
+ return;
+ }
+
+ var innerKeys = new HashSet<string>();
+ var changedResources = new List<KeyValuePair<string, object>>();
+ foreach (KeyValuePair<string, object> c in XamlResources)
+ innerKeys.Add(c.Key);
+ foreach (KeyValuePair<string, object> value in values)
+ {
+ if (innerKeys.Add(value.Key))
+ changedResources.Add(value);
+ }
+ if (changedResources.Count != 0)
+ OnResourcesChanged(changedResources);
+ }
+
+ /// <summary>
+ /// Invoked whenever the binding context of the element changes. Implement this method to add class handling for this event.
+ /// </summary>
+ /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ protected override void OnBindingContextChanged()
+ {
+ var gotBindingContext = false;
+ object bc = null;
+
+ for (var index = 0; index < Children.Count; index++)
+ {
+ Element child = Children[index];
+
+ if (!gotBindingContext)
+ {
+ bc = BindingContext;
+ gotBindingContext = true;
+ }
+
+ SetChildInheritedBindingContext(child, bc);
+ }
+ base.OnBindingContextChanged();
+ }
}
} // namespace Tizen.NUI
using System;
using Tizen.NUI.BaseComponents;
using System.ComponentModel;
-using Tizen.NUI.Binding;
namespace Tizen.NUI
{
}
}
- /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
- [EditorBrowsable(EditorBrowsableState.Never)]
- public ResourceDictionary XamlResources
- {
- get
- {
- return Application.Current.XamlResources;
- }
- set
- {
- Application.Current.XamlResources = value;
- }
- }
-
/// <summary>
/// Gets the Layer's ID
/// Readonly
if (NDalicPINVOKE.SWIGPendingException.Pending)
throw NDalicPINVOKE.SWIGPendingException.Retrieve();
Children.Add(child);
- BindableObject.SetInheritedBindingContext(child, this?.BindingContext);
+ OnChildAdded(child);
}
}
Children.Remove(child);
child.InternalParent = null;
+ OnChildRemoved(child);
}
/// <summary>
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
using System;
using System.ComponentModel;
+using System.Linq;
+using System.Reflection;
using System.Runtime.CompilerServices;
namespace Tizen.NUI.Xaml
{
/// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
- public XamlFilePathAttribute([CallerFilePath] string filePath = "")
- {
- // Unused parameter
- _ = filePath;
- }
+ public XamlFilePathAttribute([CallerFilePath] string filePath = "") => FilePath = filePath;
+
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public string FilePath { get; }
+
+ internal static string GetFilePathForObject(object view) => (view?.GetType().GetTypeInfo().GetCustomAttributes(typeof(XamlFilePathAttribute), false).FirstOrDefault() as XamlFilePathAttribute)?.FilePath;
}
}
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
XmlInfo = xmlInfo;
}
+ internal XamlParseException(string message, IServiceProvider serviceProvider, Exception innerException = null)
+ : this(message, GetLineInfo(serviceProvider), innerException)
+ {
+ }
+
/// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
[EditorBrowsable(EditorBrowsableState.Never)]
public IXmlLineInfo XmlInfo { get; private set; }
return message;
return string.Format("Position {0}:{1}. {2}", xmlinfo.LineNumber, xmlinfo.LinePosition, message);
}
+
+
+ static IXmlLineInfo GetLineInfo(IServiceProvider serviceProvider)
+ => (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) is IXmlLineInfoProvider lineInfoProvider) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo();
}
}
-/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+/*
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public static readonly BindableProperty BindingContextProperty =
- BindableProperty.Create(nameof(BindingContext), typeof(object), typeof(BindableObject), null, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) =>
- {
- var bindableObject = (BindableObject)bindable;
- if (newValue != null)
- {
- bindableObject.bindingContext = newValue;
- bindableObject.FlushBinding();
-
- if (newValue is BindableObject targetBindableObject)
- {
- targetBindableObject.IsBinded = true;
- }
- }
- }),
- defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) =>
- {
- if (null != bindable.bindingContext)
- {
- return bindable.bindingContext;
- }
-
- if (bindable is Container container)
- {
- return container.Parent?.BindingContext;
- }
- else
- {
- return null;
- }
- }));
+ BindableProperty.Create(nameof(BindingContext), typeof(object), typeof(BindableObject), default(object), BindingMode.OneWay, null, BindingContextPropertyChanged,
+ null, null, BindingContextPropertyBindingChanging);
readonly List<BindablePropertyContext> properties = new List<BindablePropertyContext>(4);
set;
} = false;
+ static void BindingContextPropertyChanged(BindableObject bindable, object oldvalue, object newvalue)
+ {
+ bindable.inheritedContext = null;
+ bindable.ApplyBindings(skipBindingContext: true, fromBindingContextChanged: true);
+ bindable.OnBindingContextChanged();
+
+ if (newvalue is BindableObject targetBindableObject)
+ {
+ targetBindableObject.IsBinded = true;
+ }
+ }
+
static void BindingContextPropertyBindingChanging(BindableObject bindable, BindingBase oldBindingBase, BindingBase newBindingBase)
{
object context = bindable.inheritedContext;
Attributes = attributes;
}
}
-
- internal void AddChildBindableObject(BindableObject child)
- {
- if (null != child)
- {
- children.Add(child);
- child.FlushBinding();
- }
- }
-
- internal void RemoveChildBindableObject(BindableObject child)
- {
- children.Remove(child);
- }
-
- private List<BindableObject> children = new List<BindableObject>();
-
- private void FlushBinding()
- {
- ApplyBindings(skipBindingContext: true, fromBindingContextChanged: true);
- OnBindingContextChanged();
-
- foreach (var child in children)
- {
- child.FlushBinding();
- }
- }
}
}
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
internal virtual void OnParentResourcesChanged(object sender, ResourcesChangedEventArgs e)
{
- // if (e == ResourcesChangedEventArgs.StyleSheets)
- // // ApplyStyleSheetsOnParentSet();
- // else
- // OnParentResourcesChanged(e.Values);
+ OnParentResourcesChanged(e.Values);
}
internal virtual void OnParentResourcesChanged(IEnumerable<KeyValuePair<string, object>> values)
object value;
if (this.TryGetResource(key, out value))
OnResourceChanged(property, value);
-
- if (null != Application.Current)
- {
- Application.Current.XamlResourceChanged += OnResourcesChanged;
- }
}
internal event EventHandler ParentSet;
-/*
+/*
* Copyright(c) 2021 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
/*
- * Copyright(c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright(c) 2022 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
-
-using Tizen.NUI.Binding.Internals;
using Tizen.NUI.Xaml;
namespace Tizen.NUI.Binding
using System.Reflection;
using Tizen.NUI.StyleSheets;
using System.ComponentModel;
+using Tizen.NUI.BaseComponents;
namespace Tizen.NUI.Binding
{
{
internal const string StyleClassPrefix = "Tizen.NUI.Binding.StyleClass.";
+ const int CleanupTrigger = 128;
+ int cleanupThreshold = CleanupTrigger;
+
readonly BindableProperty basedOnResourceProperty = BindableProperty.CreateAttached("BasedOnResource", typeof(XamlStyle), typeof(XamlStyle), default(XamlStyle),
propertyChanged: OnBasedOnResourceChanged);
if (BaseResourceKey != null)
bindable.SetDynamicResource(basedOnResourceProperty, BaseResourceKey);
ApplyCore(bindable, BasedOn ?? GetBasedOnResource(bindable));
+ CleanUpWeakReferences();
}
[EditorBrowsable(EditorBrowsableState.Never)]
static void OnBasedOnResourceChanged(BindableObject bindable, object oldValue, object newValue)
{
- // Style style = (bindable as BaseHandle).Style;
- // if (style == null)
- // return;
- // style.UnApplyCore(bindable, (Style)oldValue);
- // style.ApplyCore(bindable, (Style)newValue);
+ XamlStyle style = (bindable as View).XamlStyle;
+ if (style == null)
+ return;
+ style.UnApplyCore(bindable, (XamlStyle)oldValue);
+ style.ApplyCore(bindable, (XamlStyle)newValue);
}
void UnApplyCore(BindableObject bindable, XamlStyle basedOn)
return true;
return value.TargetType.IsAssignableFrom(TargetType);
}
- }
+
+ void CleanUpWeakReferences()
+ {
+ if (targets.Count < cleanupThreshold)
+ {
+ return;
+ }
+
+ targets.RemoveAll(t => !t.TryGetTarget(out _));
+ cleanupThreshold = targets.Count + CleanupTrigger;
+ }
+ }
}