Example #1
0
        /// <inheritdoc/>
        public override object AddValueChangedHandler(object dataItem, EventHandler <EventArgs> handler)
        {
            var reference = new BindingReference();

            reference.owner    = this;
            reference.dataItem = dataItem;
            reference.handler  = handler;
            var childItem = _parent.GetValue(dataItem);

            reference.parentReference = _parent.AddValueChangedHandler(dataItem, reference.ValueChanged);
            reference.childReference  = _child.AddValueChangedHandler(childItem, handler);
            return(reference);
        }
Example #2
0
        /// <summary>
        /// Binds to the specified child <paramref name="binding"/> of this binding.
        /// </summary>
        /// <remarks>
        /// This can be used to bind to child objects of your view model, for example
        /// <code>model.SomeProperty.ChildProperty</code>.
        /// </remarks>
        /// <example>
        /// Use this like so:
        /// <code>
        ///     public class MyChild { public SomeChildProperty { get; set; } }
        ///     public class MyModel { public ChildObject { get; set; } }
        ///
        ///     var model = new MyModel();
        ///     Binding.Property(model, (MyModel m) => m.ChildObject).Child(Binding.Property("SomeChildProperty"));
        /// </code>
        /// </example>
        /// <returns>The binding to the child property accessed through the current binding.</returns>
        /// <param name="binding">Binding to get the child value from this binding.</param>
        /// <typeparam name="TNewValue">The type of the child property value.</typeparam>
        public new BindableBinding <T, TNewValue> Child <TNewValue>(IndirectBinding <TNewValue> binding)
        {
            object childBindingReference          = null;
            EventHandler <EventArgs> eventHandler = null;
            EventHandler <EventArgs> valueChanged = (sender, e) =>
            {
                binding.RemoveValueChangedHandler(childBindingReference, eventHandler);
                eventHandler?.Invoke(sender, e);
                childBindingReference = binding.AddValueChangedHandler(DataValue, eventHandler);
            };

            return(new BindableBinding <T, TNewValue>(
                       DataItem,
                       c => binding.GetValue(DataValue),
                       (c, v) => binding.SetValue(DataValue, v),
                       addChangeEvent: (c, ev) =>
            {
                eventHandler = ev;
                DataValueChanged += valueChanged;
                childBindingReference = binding.AddValueChangedHandler(DataValue, ev);
            },
                       removeChangeEvent: (c, ev) =>
            {
                binding.RemoveValueChangedHandler(childBindingReference, ev);
                DataValueChanged -= valueChanged;
            }
                       ));
        }
Example #3
0
        /// <summary>
        /// Binds to the specified child <paramref name="binding"/> of this binding.
        /// </summary>
        /// <remarks>
        /// This can be used to bind to child objects of your view model, for example
        /// <code>model.SomeProperty.ChildProperty</code>.
        /// </remarks>
        /// <example>
        /// Use this like so:
        /// <code>
        ///     public class MyChild { public SomeChildProperty { get; set; } }
        ///     public class MyModel { public ChildObject { get; set; } }
        ///
        ///     var model = new MyModel();
        ///     Binding.Property(model, (MyModel m) => m.ChildObject).Child(Binding.Property("SomeChildProperty"));
        /// </code>
        /// </example>
        /// <returns>The binding to the child property accessed through the current binding.</returns>
        /// <param name="binding">Binding to get the child value from this binding.</param>
        /// <typeparam name="TValue">The type of the child property value.</typeparam>
        public DirectBinding <TValue> Child <TValue>(IndirectBinding <TValue> binding)
        {
            object childBindingReference          = null;
            EventHandler <EventArgs> eventHandler = null;
            EventHandler <EventArgs> valueChanged = (sender, e) =>
            {
                binding.RemoveValueChangedHandler(childBindingReference, eventHandler);
                eventHandler?.Invoke(sender, e);
                childBindingReference = binding.AddValueChangedHandler(DataValue, eventHandler);
            };

            return(new DelegateBinding <TValue>(
                       () => binding.GetValue(DataValue),
                       v => binding.SetValue(DataValue, v),
                       addChangeEvent: ev =>
            {
                eventHandler = ev;
                DataValueChanged += valueChanged;
                childBindingReference = binding.AddValueChangedHandler(DataValue, ev);
            },
                       removeChangeEvent: ev =>
            {
                binding.RemoveValueChangedHandler(childBindingReference, ev);
                DataValueChanged -= valueChanged;
            }
                       ));
        }
Example #4
0
        /// <summary>
        /// Binds to the specified child <paramref name="binding"/> of this binding.
        /// </summary>
        /// <remarks>
        /// This can be used to bind to child objects of your view model, for example
        /// <code>model.SomeProperty.ChildProperty</code>.
        /// </remarks>
        /// <example>
        /// Use this like so:
        /// <code>
        ///     public class MyChild { public SomeChildProperty { get; set; } }
        ///     public class MyModel { public ChildObject { get; set; } }
        ///
        ///     Binding.Property((MyModel m) => m.ChildObject).Child(Binding.Property("SomeChildProperty"));
        /// </code>
        /// </example>
        /// <returns>The binding to the child property accessed through the current binding.</returns>
        /// <param name="binding">Binding to get the child value from this binding.</param>
        /// <typeparam name="TNewValue">The type of the child property value.</typeparam>
        public IndirectBinding <TNewValue> Child <TNewValue>(IndirectBinding <TNewValue> binding)
        {
            object bindingReference      = null;
            object childBindingReference = null;
            object context = null;
            EventHandler <EventArgs> eventHandler = null;
            EventHandler <EventArgs> valueChanged = (sender, e) =>
            {
                binding.RemoveValueChangedHandler(childBindingReference, eventHandler);
                eventHandler?.Invoke(sender, e);
                childBindingReference = binding.AddValueChangedHandler(GetValue(context), eventHandler);
            };

            return(new DelegateBinding <object, TNewValue>(
                       c => binding.GetValue(GetValue(context = c)),
                       (c, v) => binding.SetValue(GetValue(context = c), v),
                       addChangeEvent: (c, ev) =>
            {
                context = c;
                eventHandler = ev;
                bindingReference = AddValueChangedHandler(c, valueChanged);

                childBindingReference = binding.AddValueChangedHandler(GetValue(c), ev);
            },
                       removeChangeEvent: (c, ev) =>
            {
                binding.RemoveValueChangedHandler(childBindingReference, ev);
                RemoveValueChangedHandler(bindingReference, valueChanged);
            }
                       ));
        }
Example #5
0
        /// <summary>
        /// Executes a command retrieved using the specified <paramref name="commandBinding"/> from the <paramref name="dataContext"/>.
        /// </summary>
        /// <remarks>
        /// This helper method is useful for binding general events to fire an <see cref="ICommand"/> that is in your view model.
        /// The command will only be executed if its <see cref="ICommand.CanExecute"/> returns <c>true</c>.
        ///
        /// Most controls (e.g. <see cref="Eto.Forms.Button"/>) have a special Command parameter that can be set instead,
        /// which takes into account the enabled state of the command and will enable/disable the control automatically.
        /// </remarks>
        /// <example>
        /// This example will fire the MyModel.MyCommand when the mouse is down on the specified panel.
        /// The MyModel instance is based off the panel's current DataContext.
        /// <code>
        /// var panel = new Panel();
        /// panel.MouseDown += (sender, e) => Binding.ExecuteCommand(panel.DataContext, Binding.Property((MyModel m) => m.MyCommand));
        /// </code>
        /// </example>
        /// <param name="dataContext">Data context object to get the ICommand via the commandBinding.</param>
        /// <param name="commandBinding">Binding to get the ICommand from the data context</param>
        /// <param name="parameter">Parameter to pass to the command when executing or checking if it can execute.</param>
        public static void ExecuteCommand(object dataContext, IndirectBinding <ICommand> commandBinding, object parameter = null)
        {
            var command = commandBinding.GetValue(dataContext);

            if (command != null && command.CanExecute(parameter))
            {
                command.Execute(parameter);
            }
        }
Example #6
0
        /// <summary>
        /// Binds to the specified child <paramref name="binding"/> of this binding.
        /// </summary>
        /// <remarks>
        /// This can be used to bind to child objects of your view model, for example
        /// <code>model.SomeProperty.ChildProperty</code>.
        /// </remarks>
        /// <example>
        /// Use this like so:
        /// <code>
        ///     public class MyChild { public SomeChildProperty { get; set; } }
        ///     public class MyModel { public ChildObject { get; set; } }
        ///
        ///     var model = new MyModel();
        ///     Binding.Property(model, (MyModel m) => m.ChildObject).Child(Binding.Property("SomeChildProperty"));
        /// </code>
        /// </example>
        /// <returns>The binding to the child property accessed through the current binding.</returns>
        /// <param name="binding">Binding to get the child value from this binding.</param>
        /// <typeparam name="TValue">The type of the child property value.</typeparam>
        public DirectBinding <TValue> Child <TValue>(IndirectBinding <TValue> binding)
        {
            object childBindingReference          = null;
            EventHandler <EventArgs> eventHandler = null;

            void valueChanged(object sender, EventArgs e)
            {
                binding.RemoveValueChangedHandler(childBindingReference, eventHandler);
                eventHandler?.Invoke(sender, e);
                childBindingReference = binding.AddValueChangedHandler(DataValue, eventHandler);
            }

            void setValueStruct(TValue v)
            {
                object parentValue = DataValue;

                binding.SetValue(parentValue, v);
                DataValue = (T)parentValue;
            }

            void setValueObject(TValue v) => binding.SetValue(DataValue, v);

            var isStruct = typeof(T).GetTypeInfo().IsValueType;

            return(new DelegateBinding <TValue>(
                       () => binding.GetValue(DataValue),
                       isStruct ? (Action <TValue>)setValueStruct : setValueObject,
                       addChangeEvent: ev =>
            {
                eventHandler = ev;
                DataValueChanged += valueChanged;
                childBindingReference = binding.AddValueChangedHandler(DataValue, ev);
            },
                       removeChangeEvent: ev =>
            {
                binding.RemoveValueChangedHandler(childBindingReference, ev);
                DataValueChanged -= valueChanged;
            }
                       ));
        }
Example #7
0
        /// <inheritdoc/>
        protected override TChild InternalGetValue(object dataItem)
        {
            var childItem = _parent.GetValue(dataItem);

            return(_child.GetValue(childItem));
        }