StaticResourceExtension : need to implément IXamlSchemaContextProvider in design time
-
03 Maret 2011 13:52
Hi all,
I use a bindable static resource extension that inherit from StaticResourceExtension.
It's work in run time, so very well.
But in design time, I have the error : The markup extension 'BindableStaticResource' require that 'IXamlSchemaContextProvider' is implemented in the IServiceProvider of ProvideValue.
See the BindableStaticResourceExtension code:
using System; using System.Windows; using System.Windows.Data; using System.Windows.Markup; using System.Xaml; namespace WinningGames.Core { /// <summary> /// Define a bindable static resource /// </summary> public class BindableStaticResource : StaticResourceExtension { private bool dataContextChangeHandlerSet = false; /// <summary> /// Create a bindable static resource /// </summary> public BindableStaticResource() : base() { Binding = new Binding(); } /// <summary> /// Create a bindable static resource /// </summary> /// <param name="binding">Binding used to retrive the resource key</param> public BindableStaticResource(Binding binding) : base() { Binding = binding; } /// <summary> /// Provide a value for the target property /// </summary> /// <param name="serviceProvider">Service provider for the markup extension</param> /// <returns>Value for the target property</returns> public override object ProvideValue(IServiceProvider serviceProvider) { // Get the service IProvideValueTarget provideValueTarget = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; if(provideValueTarget != null) { // Get the target element FrameworkElement targetElement = provideValueTarget.TargetObject as FrameworkElement; /* if (targetElement == null) targetElement = provideValueTarget.TargetObject as FrameworkElement;*/ if(targetElement != null) { // If the data context change handler has not been setted if(!dataContextChangeHandlerSet) { // Add an handler targetElement.DataContextChanged += new DependencyPropertyChangedEventHandler(targetElement_DataContextChanged); dataContextChangeHandlerSet = true; } // If the binding has none source if(String.IsNullOrEmpty(Binding.ElementName) && Binding.RelativeSource == null && Binding.Source == null) // Use the datacontext of the target Binding.Source = targetElement.DataContext; } } // Create a dummy object to simulate the binding DependencyObject dummyObject = new DependencyObject(); // Set the dummy binding BindingOperations.SetBinding(dummyObject, DummyProperty, Binding); // Get the binded value and use it as resource key this.ResourceKey = dummyObject.GetValue(DummyProperty); // Return the resource return ResourceKey != null ? base.ProvideValue(serviceProvider) : null; } /// <summary> /// Get or set the resource key /// </summary> public new object ResourceKey { get { return base.ResourceKey; } set { // We accept a null value without set it if(value != null) base.ResourceKey = value; } } /// <summary> /// Get or set the binding used to retrieve the resource key /// </summary> public Binding Binding { get; set; } /// <summary> /// Occurs when the datacontext of the target object has changed /// </summary> /// <param name="sender">Event sender</param> /// <param name="e">Event argument</param> private void targetElement_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { /*Binding = new Binding(); Binding.Path = new PropertyPath("Name"); ProvideValue(serviceProvider);*/ // TODO : Call the ProvideValue method } /// <summary> /// Dummy property used to simulate the binding /// </summary> private static readonly DependencyProperty DummyProperty = DependencyProperty.Register("Dummy", typeof(object), typeof(DependencyObject)); } }
and the use :
<UserControl x:Class="WinningGames.PieceView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:core="clr-namespace:WinningGames.Core" Height="45" Width="45" DataContext="{Binding Piece, Source={StaticResource Locator}}" Grid.Column="{Binding X}" Grid.Row="{Binding Y}"> <UserControl.Resources> <ResourceDictionary Source="Resources/ResourceDictionary.xaml" /> </UserControl.Resources> <UserControl.Content> <core:BindableStaticResource Binding="{Binding Name}" /> </UserControl.Content> </UserControl>
Have you an idea to help me?
Thanks