#if XFORMS
namespace Caliburn.Micro.Core.Xamarin.Forms
#else
namespace Caliburn.Micro
#endif
{
using System;
#if WinRT
using Windows.UI.Xaml;
using Windows.UI.Xaml.Data;
#elif XFORMS
using global::Xamarin.Forms;
using UIElement = global::Xamarin.Forms.Element;
using FrameworkElement = global::Xamarin.Forms.VisualElement;
using DependencyProperty = global::Xamarin.Forms.BindableProperty;
using DependencyObject =global::Xamarin.Forms.BindableObject;
#else
using System.Windows;
using System.Windows.Data;
using Caliburn.Micro.Core;
#endif
///
/// Hosts dependency properties for binding.
///
public static class Bind {
///
/// Allows binding on an existing view. Use this on root UserControls, Pages and Windows; not in a DataTemplate.
///
public static DependencyProperty ModelProperty =
DependencyPropertyHelper.RegisterAttached(
"Model",
typeof(object),
typeof(Bind),
null,
ModelChanged);
///
/// Allows binding on an existing view without setting the data context. Use this from within a DataTemplate.
///
public static DependencyProperty ModelWithoutContextProperty =
DependencyPropertyHelper.RegisterAttached(
"ModelWithoutContext",
typeof(object),
typeof(Bind),
null,
ModelWithoutContextChanged);
internal static DependencyProperty NoContextProperty =
DependencyPropertyHelper.RegisterAttached(
"NoContext",
typeof(bool),
typeof(Bind),
false);
///
/// Gets the model to bind to.
///
/// The dependency object to bind to.
/// The model.
public static object GetModelWithoutContext(DependencyObject dependencyObject) {
return dependencyObject.GetValue(ModelWithoutContextProperty);
}
///
/// Sets the model to bind to.
///
/// The dependency object to bind to.
/// The model.
public static void SetModelWithoutContext(DependencyObject dependencyObject, object value) {
dependencyObject.SetValue(ModelWithoutContextProperty, value);
}
///
/// Gets the model to bind to.
///
/// The dependency object to bind to.
/// The model.
public static object GetModel(DependencyObject dependencyObject) {
return dependencyObject.GetValue(ModelProperty);
}
///
/// Sets the model to bind to.
///
/// The dependency object to bind to.
/// The model.
public static void SetModel(DependencyObject dependencyObject, object value) {
dependencyObject.SetValue(ModelProperty, value);
}
static void ModelChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
if (View.InDesignMode || e.NewValue == null || e.NewValue == e.OldValue) {
return;
}
var fe = d as FrameworkElement;
if (fe == null) {
return;
}
View.ExecuteOnLoad(fe, delegate {
var target = e.NewValue;
d.SetValue(View.IsScopeRootProperty, true);
#if XFORMS
var context = fe.Id.ToString("N");
#else
var context = string.IsNullOrEmpty(fe.Name)
? fe.GetHashCode().ToString()
: fe.Name;
#endif
ViewModelBinder.Bind(target, d, context);
});
}
static void ModelWithoutContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
if (View.InDesignMode || e.NewValue == null || e.NewValue == e.OldValue) {
return;
}
var fe = d as FrameworkElement;
if (fe == null) {
return;
}
View.ExecuteOnLoad(fe, delegate {
var target = e.NewValue;
var containerKey = e.NewValue as string;
if (containerKey != null) {
LogManager.GetLog(typeof(Bind)).Info("Using IoC is deprecated and will be removed in v3.0");
target = IoC.GetInstance(null, containerKey);
}
d.SetValue(View.IsScopeRootProperty, true);
#if XFORMS
var context = fe.Id.ToString("N");
#else
var context = string.IsNullOrEmpty(fe.Name)
? fe.GetHashCode().ToString()
: fe.Name;
#endif
d.SetValue(NoContextProperty, true);
ViewModelBinder.Bind(target, d, context);
});
}
///
/// Allows application of conventions at design-time.
///
public static DependencyProperty AtDesignTimeProperty =
DependencyPropertyHelper.RegisterAttached(
"AtDesignTime",
typeof(bool),
typeof(Bind),
false,
AtDesignTimeChanged);
///
/// Gets whether or not conventions are being applied at design-time.
///
/// The ui to apply conventions to.
/// Whether or not conventions are applied.
#if NET
[AttachedPropertyBrowsableForTypeAttribute(typeof(DependencyObject))]
#endif
public static bool GetAtDesignTime(DependencyObject dependencyObject) {
return (bool)dependencyObject.GetValue(AtDesignTimeProperty);
}
///
/// Sets whether or not do bind conventions at design-time.
///
/// The ui to apply conventions to.
/// Whether or not to apply conventions.
public static void SetAtDesignTime(DependencyObject dependencyObject, bool value) {
dependencyObject.SetValue(AtDesignTimeProperty, value);
}
static void AtDesignTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
if (!View.InDesignMode)
return;
var atDesignTime = (bool) e.NewValue;
if (!atDesignTime)
return;
#if XFORMS
d.SetBinding(DataContextProperty, String.Empty);
#else
BindingOperations.SetBinding(d, DataContextProperty, new Binding());
#endif
}
static readonly DependencyProperty DataContextProperty =
DependencyPropertyHelper.RegisterAttached(
"DataContext",
typeof(object),
typeof(Bind),
null, DataContextChanged);
static void DataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
if (!View.InDesignMode)
return;
var enable = d.GetValue(AtDesignTimeProperty);
if (enable == null || ((bool)enable) == false || e.NewValue == null)
return;
var fe = d as FrameworkElement;
if (fe == null)
return;
#if XFORMS
ViewModelBinder.Bind(e.NewValue, d, fe.Id.ToString("N"));
#else
ViewModelBinder.Bind(e.NewValue, d, string.IsNullOrEmpty(fe.Name) ? fe.GetHashCode().ToString() : fe.Name);
#endif
}
}
}