Skip to content

Instantly share code, notes, and snippets.

@mhudasch
Created July 27, 2017 07:45
Show Gist options
  • Save mhudasch/7e85bfebe91c333fe96ac62b6ec5567b to your computer and use it in GitHub Desktop.
Save mhudasch/7e85bfebe91c333fe96ac62b6ec5567b to your computer and use it in GitHub Desktop.
Inject a View into another
[DefaultProperty("ViewPropertyBindings")]
[ContentProperty("ViewPropertyBindings")]
internal class InjectedView : FrameworkElement
{
private readonly IKernel kernel;
private FrameworkElement visual;
private ObservableCollection<ViewPropertyBinding> viewPropertyBindings;
public Type ViewType { get; set; }
public InjectedView()
{
if (!DesignerProperties.GetIsInDesignMode(this))
{
this.kernel = ((IApplicationRoot)Application.Current).Get<IKernel>();
}
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (this.visual == null)
{
if (!DesignerProperties.GetIsInDesignMode(this))
{
this.visual = this.kernel.Get(this.ViewType) as FrameworkElement;
}
if (this.viewPropertyBindings != null && this.visual != null)
{
foreach (var boundProperty in this.viewPropertyBindings)
{
var binding = BindingOperations.GetBinding(boundProperty, ViewPropertyBinding.BindingProperty);
var dp = GetDependencyPropertyByName(this.visual, boundProperty.PropertyName + "Property");
if (binding != null && dp != null)
{
this.AddLogicalChild(boundProperty);
this.AddVisualChild(boundProperty);
BindingOperations.SetBinding(this.visual, dp, binding);
BindingOperations.ClearBinding(boundProperty, ViewPropertyBinding.BindingProperty);
}
else if(binding == null && dp != null && boundProperty.Binding != null)
{
this.visual.SetValue(dp, boundProperty.Binding);
}
}
}
this.AddLogicalChild(visual);
this.AddVisualChild(visual);
this.InvalidateMeasure();
}
}
private static DependencyProperty GetDependencyPropertyByName(DependencyObject dependencyObject, string dpName)
{
return GetDependencyPropertyByName(dependencyObject.GetType(), dpName);
}
private static DependencyProperty GetDependencyPropertyByName(Type dependencyObjectType, string dpName)
{
DependencyProperty dp = null;
var fieldInfo = dependencyObjectType.GetField(dpName, BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
if (fieldInfo != null)
{
dp = fieldInfo.GetValue(null) as DependencyProperty;
}
return dp;
}
protected override Visual GetVisualChild(int index)
{
return index == 0 ? this.visual : null;
}
protected override int VisualChildrenCount
{
get
{
return this.visual != null ? 1 : 0;
}
}
protected override Size ArrangeOverride(Size finalSize)
{
if (this.visual != null)
{
this.visual.Arrange(new Rect(finalSize));
}
return finalSize;
}
protected override Size MeasureOverride(Size availableSize)
{
if (this.visual != null)
{
this.visual.Measure(availableSize);
return this.visual.DesiredSize;
}
return availableSize;
}
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ObservableCollection<ViewPropertyBinding> ViewPropertyBindings
{
get
{
if (this.viewPropertyBindings == null)
{
this.viewPropertyBindings = new ObservableCollection<ViewPropertyBinding>();
}
return this.viewPropertyBindings;
}
}
}
internal class ViewPropertyBinding : FrameworkElement
{
public string PropertyName { get; set; }
public object Binding
{
get { return (object)this.GetValue(BindingProperty); }
set { this.SetValue(BindingProperty, value); }
}
public static readonly DependencyProperty BindingProperty =
DependencyProperty.Register("Binding", typeof(object), typeof(ViewPropertyBinding), new PropertyMetadata(null));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment