/// <summary> /// Adds an item to the list /// /// * If the list has no type the type will be infered from the given object /// * If the list has no type and `null` is added the type will be set as `object` /// </summary> /// <param name="obj"></param> /// <exception cref="Exception">If the given object is not assignable to the list type</exception> public void Add(object obj) { if (null == m_Items) { // Special case when adding an element and we have no items // Dynamically create the list and properties to be strongly typed. We must use activator in this situation var type = obj?.GetType() ?? typeof(object); m_Items = Activator.CreateInstance(typeof(List <>).MakeGenericType(type)); m_ItemsProperty = CreateItemsProperty(type); m_PropertyBag.AddProperty(m_ItemsProperty); } if (obj is UTinyObject) { // Special case for tiny object. We DON'T want to retain the given instance. // Instead we create a new object and deep copy the values in. This way the object // Will propegate version changes to this list var v = new UTinyObject(m_Registry, m_Type, this); v.CopyFrom((UTinyObject)obj); var typedList = (IListProperty <UTinyList, UTinyObject>)m_ItemsProperty; typedList.Add(this, v); } else { try { var converted = Convert(obj, m_ItemsProperty.ItemType); m_ItemsProperty.AddObject(this, converted); } catch (Exception e) { throw new Exception($"UTinyList.Add Type mismatch expected instance of Type=[{m_ItemsProperty.ItemType}] received Type=[{obj?.GetType()}]", e); } } }
static void Main() { PropertyBag.AddProperty("UserName", typeof(string), new DisplayNameAttribute("User Name")); PropertyBag.AddProperty("DateOfBirth", typeof(DateTime), new DisplayNameAttribute("Date of Birth")); BindingList <PropertyBag> list = new BindingList <PropertyBag>() { new PropertyBag().With("UserName", "Fred").With("DateOfBirth", new DateTime(1998, 12, 1)), new PropertyBag().With("UserName", "William").With("DateOfBirth", new DateTime(1997, 4, 23)) }; Application.Run(new Form { Controls = { new DataGridView { // prove it works for complex bindings Dock = DockStyle.Fill, DataSource = list, ReadOnly = false, AllowUserToAddRows= true } }, DataBindings = { { "Text", list, "UserName" } // prove it works for simple bindings } }); }
public override void OnPropertyUpdated(Guid bag, Property p) { switch (p.PropertyId) { case (int)TSPropertyID.GamesPlayed: case (int)TSPropertyID.RatingMean: case (int)TSPropertyID.RatingStandardDeviation: m_Properties.AddProperty(p); break; } base.OnPropertyUpdated(bag, p); }
void ISignal_BuilderAdapter.BuilderAppendProperty(IProperty property) { _properties.AddProperty(property); }
public override void AddConstraint(IProperty property) { _constraints.AddProperty(property); }
/// <summary> /// This method does a lot of magic /// You can associate ANY value with a name and the correct property will be generated for you /// </summary> public object this[string key] { get { // Incurs a dictionary lookup var property = m_PropertyBag.FindProperty(key); // Must asset to avoid undefined behaviour Assert.IsNotNull(property, $"Property '{key}' does not exist on object"); var container = (IPropertyContainer)this; // This works well since the implementation details are abstracted // i.e. We don't care how the value is unpacked (List, Dictionary, NativeArray etc) return(property.GetObjectValue(container)); } set { // Incurs a dictionary lookup var property = m_PropertyBag.FindProperty(key); if (null == property) { // Auto-generate a dynamic property for the user var type = value?.GetType() ?? typeof(object); property = CreateDynamicProperty(key, type); Assert.IsNotNull(property); m_PropertyBag.AddProperty(property); if (null == m_DynamicValues) { m_DynamicValues = new Dictionary <string, object>(); } // Setup the underlying storage // This breaks our abstraction but must be done at some point if (typeof(UTinyObject) == type) { var obj = new UTinyObject(m_Object.Registry, UTinyType.Reference.None); obj.CopyFrom(value as UTinyObject); m_DynamicValues.Add(key, obj); } else if (typeof(UTinyList) == type) { var obj = new UTinyList(m_Object.Registry, UTinyType.Reference.None); obj.CopyFrom(value as UTinyList); m_DynamicValues.Add(key, obj); } else { m_DynamicValues.Add(key, value); } } else { // @TODO There is an unhandled case here when we encounter a type mis-match, we need to detect this and throw try { property.SetObjectValue(this, value); } catch (InvalidCastException) { Debug.LogError($"Could not cast {value.GetType()} to {property.ValueType}. Value is '{value}'."); throw; } } } }
internal void BuilderAppendProperty(Property property) { _properties.AddProperty(property); }
public void AddConstraint(Property property) { _constraints.AddProperty(property); }