Created
February 8, 2018 22:09
-
-
Save brinko99/e242b79f4eaec30e834c6d3db2bd17d6 to your computer and use it in GitHub Desktop.
.NET WPF Binding markup extension supporting designer specific value
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.ComponentModel; | |
using System.Windows; | |
using System.Windows.Data; | |
using System.Windows.Markup; | |
using static System.Convert; | |
namespace MarkupExtensions | |
{ | |
/// <summary> | |
/// Markup extension that provides a binding that supports designer specific value. | |
/// </summary> | |
/// <remarks> | |
/// The binding is used in place of a typical binding. Within the designer, the specified <see cref="DesignTimeValue"/> will be used | |
/// instead of the binding specified. | |
/// <p/> | |
/// Typically simple values are passed into the extension as strings. <see cref="DesignTimeValueType"/> can specify a type to which to | |
/// convert the value through <see cref="ChangeType(object, TypeCode)"/>. | |
/// <p/> | |
/// Concept borrowed from: <see href="https://stackoverflow.com/a/38011434/84522"/> | |
/// </remarks> | |
/// <example> | |
/// <code><![CDATA[ | |
/// <RowDefinition MaxHeight="{cm:BindingWithDesignSupport | |
/// {Binding ElementName = RealTimeView, Path = ActualHeight, Mode = OneTime}, | |
/// DesignTimeValue=300, DesignTimeValueType={x:Type sys:Double}}"/> | |
/// ]]></code> | |
/// </example> | |
/// <seealso cref="MarkupExtension" /> | |
public class BindingWithDesignSupport : MarkupExtension | |
{ | |
private static readonly bool IsInDesignMode = DesignerProperties.GetIsInDesignMode(new DependencyObject()); | |
private readonly object _unsetObject = new object(); | |
/// <summary> | |
/// Initializes a new instance of the <see cref="BindingWithDesignSupport" /> class. | |
/// </summary> | |
public BindingWithDesignSupport() | |
{ | |
DesignTimeValue = _unsetObject; | |
} | |
/// <summary> | |
/// Initializes a new instance of the <see cref="BindingWithDesignSupport" /> class. | |
/// </summary> | |
/// <param name="binding">The binding.</param> | |
public BindingWithDesignSupport(BindingBase binding) | |
: this() | |
{ | |
Binding = binding ?? throw new ArgumentNullException(nameof(binding)); | |
} | |
/// <summary> | |
/// Gets or sets the binding (required). | |
/// </summary> | |
public BindingBase Binding { get; set; } | |
/// <summary> | |
/// Gets or sets the design time value (required). | |
/// </summary> | |
public object DesignTimeValue { get; set; } | |
/// <summary> | |
/// Gets or sets the type of the design time value (optional). | |
/// </summary> | |
public Type DesignTimeValueType { get; set; } | |
/// <inheritdoc /> | |
/// <param name="serviceProvider">The parameter is not used.</param> | |
public override object ProvideValue(IServiceProvider serviceProvider) | |
{ | |
if (Binding == null) | |
{ | |
throw new InvalidOperationException($"Required property '{nameof(Binding)}' is unset."); | |
} | |
if (DesignTimeValue == _unsetObject) | |
{ | |
throw new InvalidOperationException($"Required property '{nameof(DesignTimeValue)}' is unset."); | |
} | |
if (DesignTimeValueType != null) | |
{ | |
DesignTimeValue = ChangeType(DesignTimeValue, DesignTimeValueType); | |
} | |
return IsInDesignMode ? DesignTimeValue : Binding.ProvideValue(serviceProvider); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Gist referenced here: https://stackoverflow.com/a/38011434/84522