Browse Source

Merge pull request #6566 from AvaloniaUI/fixes/compiled-binding-support-IDataContextProvider

CompiledBinding correctly locates IDataContextProvider as anchor.
pull/6572/head
Dan Walmsley 5 years ago
committed by GitHub
parent
commit
d87fc7b9d0
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 23
      src/Markup/Avalonia.Markup.Xaml/Extensions.cs
  2. 18
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindingExtension.cs
  3. 23
      src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ReflectionBindingExtension.cs

23
src/Markup/Avalonia.Markup.Xaml/Extensions.cs

@ -2,7 +2,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using Avalonia.Controls;
using Avalonia.Markup.Xaml.XamlIl.Runtime; using Avalonia.Markup.Xaml.XamlIl.Runtime;
using Avalonia.Styling;
namespace Avalonia.Markup.Xaml namespace Avalonia.Markup.Xaml
{ {
@ -32,5 +34,26 @@ namespace Avalonia.Markup.Xaml
string name = string.IsNullOrEmpty(namespacePrefix) ? type : $"{namespacePrefix}:{type}"; string name = string.IsNullOrEmpty(namespacePrefix) ? type : $"{namespacePrefix}:{type}";
return tr?.Resolve(name); return tr?.Resolve(name);
} }
public static object GetDefaultAnchor(this IServiceProvider provider)
{
// If the target is not a control, so we need to find an anchor that will let us look
// up named controls and style resources. First look for the closest IControl in
// the context.
object anchor = provider.GetFirstParent<IControl>();
if (anchor is null)
{
// Try to find IDataContextProvider, this was added to allow us to find
// a datacontext for Application class when using NativeMenuItems.
anchor = provider.GetFirstParent<IDataContextProvider>();
}
// If a control was not found, then try to find the highest-level style as the XAML
// file could be a XAML file containing only styles.
return anchor ??
provider.GetService<IRootObjectProvider>()?.RootObject as IStyle ??
provider.GetLastParent<IStyle>();
}
} }
} }

18
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindingExtension.cs

@ -1,7 +1,5 @@
using System; using System;
using Avalonia.Data; using Avalonia.Data;
using Avalonia.Controls;
using Avalonia.Styling;
using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings; using Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings;
using Avalonia.Data.Core; using Avalonia.Data.Core;
using Avalonia.Markup.Parsers; using Avalonia.Markup.Parsers;
@ -33,24 +31,10 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Priority = Priority, Priority = Priority,
StringFormat = StringFormat, StringFormat = StringFormat,
Source = Source, Source = Source,
DefaultAnchor = new WeakReference(GetDefaultAnchor(provider)) DefaultAnchor = new WeakReference(provider.GetDefaultAnchor())
}; };
} }
private static object GetDefaultAnchor(IServiceProvider provider)
{
// If the target is not a control, so we need to find an anchor that will let us look
// up named controls and style resources. First look for the closest IControl in
// the context.
object anchor = provider.GetFirstParent<IControl>();
// If a control was not found, then try to find the highest-level style as the XAML
// file could be a XAML file containing only styles.
return anchor ??
provider.GetService<IRootObjectProvider>()?.RootObject as IStyle ??
provider.GetLastParent<IStyle>();
}
protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject target, AvaloniaProperty targetProperty, object anchor, bool enableDataValidation) protected override ExpressionObserver CreateExpressionObserver(IAvaloniaObject target, AvaloniaProperty targetProperty, object anchor, bool enableDataValidation)
{ {
if (Source != null) if (Source != null)

23
src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ReflectionBindingExtension.cs

@ -37,33 +37,12 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Source = Source, Source = Source,
StringFormat = StringFormat, StringFormat = StringFormat,
RelativeSource = RelativeSource, RelativeSource = RelativeSource,
DefaultAnchor = new WeakReference(GetDefaultAnchor(descriptorContext)), DefaultAnchor = new WeakReference(descriptorContext.GetDefaultAnchor()),
TargetNullValue = TargetNullValue, TargetNullValue = TargetNullValue,
NameScope = new WeakReference<INameScope>(serviceProvider.GetService<INameScope>()) NameScope = new WeakReference<INameScope>(serviceProvider.GetService<INameScope>())
}; };
} }
private static object GetDefaultAnchor(IServiceProvider context)
{
// If the target is not a control, so we need to find an anchor that will let us look
// up named controls and style resources. First look for the closest IControl in
// the context.
object anchor = context.GetFirstParent<IControl>();
if(anchor is null)
{
// Try to find IDataContextProvider, this was added to allow us to find
// a datacontext for Application class when using NativeMenuItems.
anchor = context.GetFirstParent<IDataContextProvider>();
}
// If a control was not found, then try to find the highest-level style as the XAML
// file could be a XAML file containing only styles.
return anchor ??
context.GetService<IRootObjectProvider>()?.RootObject as IStyle ??
context.GetLastParent<IStyle>();
}
public IValueConverter Converter { get; set; } public IValueConverter Converter { get; set; }
public object ConverterParameter { get; set; } public object ConverterParameter { get; set; }

Loading…
Cancel
Save