| File: System\Windows\Forms\DataBinding\PropertyManager.cs | Web Access |
| Project: src\winforms\src\System.Windows.Forms\System.Windows.Forms.csproj (System.Windows.Forms) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Collections; using System.ComponentModel; namespace System.Windows.Forms; public class PropertyManager : BindingManagerBase { private object? _dataSource; private readonly string? _propName; private PropertyDescriptor? _propInfo; private bool _bound; /// <summary> /// An object that represents the object to which the property belongs. /// </summary> public override object? Current => _dataSource; private void PropertyChanged(object? sender, EventArgs ea) { EndCurrentEdit(); OnCurrentChanged(EventArgs.Empty); } private protected override void SetDataSource(object? dataSource) { if (_dataSource is not null && !string.IsNullOrEmpty(_propName)) { _propInfo?.RemoveValueChanged(_dataSource, PropertyChanged); _propInfo = null; } _dataSource = dataSource; if (_dataSource is not null && !string.IsNullOrEmpty(_propName)) { _propInfo = TypeDescriptor.GetProperties(_dataSource).Find(_propName, true) ?? throw new ArgumentException(string.Format(SR.PropertyManagerPropDoesNotExist, _propName, dataSource)); _propInfo.AddValueChanged(_dataSource, PropertyChanged); } } public PropertyManager() { } internal PropertyManager(object dataSource) : base(dataSource) { } internal PropertyManager(object? dataSource, string propName) : base() { _propName = propName; SetDataSource(dataSource); } internal override PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[]? listAccessors) { return ListBindingHelper.GetListItemProperties(_dataSource, listAccessors); } internal override Type BindType => _dataSource!.GetType(); internal override string GetListName() { return $"{TypeDescriptor.GetClassName(_dataSource!)}.{_propName}"; } public override void SuspendBinding() { EndCurrentEdit(); if (_bound) { try { _bound = false; UpdateIsBinding(); } catch { _bound = true; UpdateIsBinding(); throw; } } } /// <summary> /// Resumes data binding. /// </summary> public override void ResumeBinding() { OnCurrentChanged(EventArgs.Empty); if (!_bound) { try { _bound = true; UpdateIsBinding(); } catch { _bound = false; UpdateIsBinding(); throw; } } } /// <summary> /// Gets the name of the list supplying the data for the binding. /// </summary> /// <returns>Always returns an empty string.</returns> protected internal override string GetListName(ArrayList? listAccessors) => string.Empty; /// <summary> /// Cancels the current edit. /// </summary> public override void CancelCurrentEdit() { IEditableObject? obj = Current as IEditableObject; obj?.CancelEdit(); PushData(); } /// <summary> /// Ends the current edit. /// </summary> public override void EndCurrentEdit() { PullData(out bool success); if (success) { IEditableObject? obj = Current as IEditableObject; obj?.EndEdit(); } } protected override void UpdateIsBinding() { for (int i = 0; i < Bindings.Count; i++) { Bindings[i].UpdateIsBinding(); } } /// <summary> /// Raises the <see cref="BindingManagerBase.CurrentChanged" /> event. /// </summary> /// <param name="ea">The event data.</param> protected internal override void OnCurrentChanged(EventArgs ea) { PushData(); onCurrentChangedHandler?.Invoke(this, ea); _onCurrentItemChangedHandler?.Invoke(this, ea); } /// <summary> /// Raises the <see cref="BindingManagerBase.CurrentItemChanged" /> event. /// </summary> /// <param name="ea">The event data.</param> protected internal override void OnCurrentItemChanged(EventArgs ea) { PushData(); _onCurrentItemChangedHandler?.Invoke(this, ea); } internal override object? DataSource => _dataSource; internal override bool IsBinding => _dataSource is not null; /// <summary> /// Gets the position in the underlying list that controls bound to this data source point to. /// </summary> /// <value>Always returns 0.</value> public override int Position { get => 0; set { } } /// <summary> /// Gets the number of rows managed by the <see cref="BindingManagerBase" />. /// </summary> /// <value>Always returns 1.</value> public override int Count => 1; /// <summary> /// Throws a <see cref="NotSupportedException" /> in all cases. /// </summary> /// <exception cref="NotSupportedException">In all cases.</exception> public override void AddNew() { throw new NotSupportedException(SR.DataBindingAddNewNotSupportedOnPropertyManager); } /// <summary> /// Throws a <see cref="NotSupportedException" /> in all cases. /// </summary> /// <param name="index">The index of the row to delete.</param> /// <exception cref="NotSupportedException">In all cases.</exception> public override void RemoveAt(int index) { throw new NotSupportedException(SR.DataBindingRemoveAtNotSupportedOnPropertyManager); } }