using System;
using System.Reflection;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Markup;
using Microsoft.Xaml.Interactivity;
namespace LiveCharts.Uwp.Components.MultiBinding
{
///
/// The behavior that enables multiple binding.
///
[ContentProperty(Name = "Items")]
[TypeConstraint(typeof(FrameworkElement))]
public class MultiBindingBehavior : Behavior
{
///
/// Gets the collection within this instance.
///
/// One or more objects.
public MultiBindingItemCollection Items
{
get { return (MultiBindingItemCollection)GetValue(ItemsProperty); }
private set { SetValue(ItemsProperty, value); }
}
///
/// Identifier for the dependency property.
///
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register(nameof(Items), typeof(MultiBindingItemCollection), typeof(MultiBindingBehavior), null);
///
/// Gets or sets the path to the binding source property.
///
/// The path to the binding source property.
public string PropertyName
{
get { return (string)GetValue(PropertyNameProperty); }
set { SetValue(PropertyNameProperty, value); }
}
///
/// Identifier for the dependency property.
///
public static readonly DependencyProperty PropertyNameProperty =
DependencyProperty.Register(nameof(PropertyName), typeof(string), typeof(MultiBindingBehavior), new PropertyMetadata(null, OnPropertyChanged));
///
/// Gets or sets the converter to use to convert the source values to or from the target value.
///
/// A resource reference to a class that implements the interface, which includes implementations of the and methods.
public IValueConverter Converter
{
get { return (IValueConverter)GetValue(ConverterProperty); }
set { SetValue(ConverterProperty, value); }
}
///
/// Identifier for the dependency property.
///
public static readonly DependencyProperty ConverterProperty =
DependencyProperty.Register(nameof(Converter), typeof(IValueConverter), typeof(MultiBindingBehavior), new PropertyMetadata(null, OnPropertyChanged));
///
/// Gets or sets an optional parameter to pass to the converter as additional information.
///
/// A value of the type expected by the converter, which might be an object element or a string depending on the definition and XAML capabilities both of the property type being used and of the implementation of the converter.
public object ConverterParameter
{
get { return GetValue(ConverterParameterProperty); }
set { SetValue(ConverterParameterProperty, value); }
}
///
/// Identifier for the dependency property.
///
public static readonly DependencyProperty ConverterParameterProperty =
DependencyProperty.Register(nameof(ConverterParameter), typeof(object), typeof(MultiBindingBehavior), new PropertyMetadata(null, OnPropertyChanged));
///
/// Gets or sets a value that indicates the direction of the data flow in the binding.
///
/// A value that indicates the direction of the data flow in the binding.
public BindingMode Mode
{
get { return (BindingMode)GetValue(ModeProperty); }
set { SetValue(ModeProperty, value); }
}
///
/// Identifier for the dependency property.
///
public static readonly DependencyProperty ModeProperty =
DependencyProperty.Register(nameof(Mode), typeof(BindingMode), typeof(MultiBindingBehavior), new PropertyMetadata(BindingMode.OneWay, OnPropertyChanged));
private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var multiBindingBehavior = (MultiBindingBehavior)d;
multiBindingBehavior.Update();
}
///
/// Initializes a new instance of the class.
///
public MultiBindingBehavior()
{
Items = new MultiBindingItemCollection();
}
///
/// Called after the behavior is attached to an AssociatedObject.
///
/// Override this to hook up functionality to the AssociatedObject.
protected override void OnAttached()
{
base.OnAttached();
Update();
}
private void Update()
{
if (AssociatedObject == null || string.IsNullOrEmpty(PropertyName))
{
return;
}
var targetProperty = PropertyName;
Type targetType;
if (targetProperty.Contains("."))
{
var propertyNameParts = targetProperty.Split('.');
targetType = Type.GetType(string.Format("Windows.UI.Xaml.Controls.{0}, Windows",
propertyNameParts[0]));
targetProperty = propertyNameParts[1];
}
else
{
targetType = AssociatedObject.GetType();
}
PropertyInfo targetDependencyPropertyField = null;
while (targetDependencyPropertyField == null && targetType != null)
{
var targetTypeInfo = targetType.GetTypeInfo();
targetDependencyPropertyField = targetTypeInfo.GetDeclaredProperty(targetProperty + "Property");
targetType = targetTypeInfo.BaseType;
}
if (targetDependencyPropertyField == null) return;
var targetDependencyProperty = (DependencyProperty)targetDependencyPropertyField.GetValue(null);
var binding = new Binding()
{
Path = new PropertyPath("Value"),
Source = Items,
Converter = Converter,
ConverterParameter = ConverterParameter,
Mode = Mode
};
BindingOperations.SetBinding(AssociatedObject, targetDependencyProperty, binding);
}
}
}