224 lines
7.9 KiB
C#
224 lines
7.9 KiB
C#
|
#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
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Hosts dependency properties for binding.
|
|||
|
/// </summary>
|
|||
|
public static class Bind {
|
|||
|
/// <summary>
|
|||
|
/// Allows binding on an existing view. Use this on root UserControls, Pages and Windows; not in a DataTemplate.
|
|||
|
/// </summary>
|
|||
|
public static DependencyProperty ModelProperty =
|
|||
|
DependencyPropertyHelper.RegisterAttached(
|
|||
|
"Model",
|
|||
|
typeof(object),
|
|||
|
typeof(Bind),
|
|||
|
null,
|
|||
|
ModelChanged);
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Allows binding on an existing view without setting the data context. Use this from within a DataTemplate.
|
|||
|
/// </summary>
|
|||
|
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);
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets the model to bind to.
|
|||
|
/// </summary>
|
|||
|
/// <param name = "dependencyObject">The dependency object to bind to.</param>
|
|||
|
/// <returns>The model.</returns>
|
|||
|
public static object GetModelWithoutContext(DependencyObject dependencyObject) {
|
|||
|
return dependencyObject.GetValue(ModelWithoutContextProperty);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Sets the model to bind to.
|
|||
|
/// </summary>
|
|||
|
/// <param name = "dependencyObject">The dependency object to bind to.</param>
|
|||
|
/// <param name = "value">The model.</param>
|
|||
|
public static void SetModelWithoutContext(DependencyObject dependencyObject, object value) {
|
|||
|
dependencyObject.SetValue(ModelWithoutContextProperty, value);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets the model to bind to.
|
|||
|
/// </summary>
|
|||
|
/// <param name = "dependencyObject">The dependency object to bind to.</param>
|
|||
|
/// <returns>The model.</returns>
|
|||
|
public static object GetModel(DependencyObject dependencyObject) {
|
|||
|
return dependencyObject.GetValue(ModelProperty);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Sets the model to bind to.
|
|||
|
/// </summary>
|
|||
|
/// <param name = "dependencyObject">The dependency object to bind to.</param>
|
|||
|
/// <param name = "value">The model.</param>
|
|||
|
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);
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Allows application of conventions at design-time.
|
|||
|
/// </summary>
|
|||
|
public static DependencyProperty AtDesignTimeProperty =
|
|||
|
DependencyPropertyHelper.RegisterAttached(
|
|||
|
"AtDesignTime",
|
|||
|
typeof(bool),
|
|||
|
typeof(Bind),
|
|||
|
false,
|
|||
|
AtDesignTimeChanged);
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Gets whether or not conventions are being applied at design-time.
|
|||
|
/// </summary>
|
|||
|
/// <param name="dependencyObject">The ui to apply conventions to.</param>
|
|||
|
/// <returns>Whether or not conventions are applied.</returns>
|
|||
|
#if NET
|
|||
|
[AttachedPropertyBrowsableForTypeAttribute(typeof(DependencyObject))]
|
|||
|
#endif
|
|||
|
public static bool GetAtDesignTime(DependencyObject dependencyObject) {
|
|||
|
return (bool)dependencyObject.GetValue(AtDesignTimeProperty);
|
|||
|
}
|
|||
|
|
|||
|
/// <summary>
|
|||
|
/// Sets whether or not do bind conventions at design-time.
|
|||
|
/// </summary>
|
|||
|
/// <param name="dependencyObject">The ui to apply conventions to.</param>
|
|||
|
/// <param name="value">Whether or not to apply conventions.</param>
|
|||
|
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
|
|||
|
}
|
|||
|
}
|
|||
|
}
|