Using StaticResource as an argument for MarkupExtension throws a NullReferenceException in WPF

Even after simplifying the problem to the minimum code, I still cannot figure out what might cause a NullReferenceException .

Create a new WPF application "MarkupExtParam". Replace Code:

MainWindow.xaml:

 <Window x:Class="MarkupExtParam.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:my="clr-namespace:MarkupExtParam" Content="{Binding}"> <Control.DataContext> <my:Foo/> </Control.DataContext> <Control.Resources> <my:Foo x:Key="foo"/> <DataTemplate DataType="{x:Type my:Foo}"> <TextBlock Text="{my:Ext {StaticResource foo}}"/> </DataTemplate> </Control.Resources> </Window> 

MainWindow.xaml.cs:

 using System; using System.Windows.Markup; namespace MarkupExtParam { public partial class MainWindow { public MainWindow () { InitializeComponent(); } } [MarkupExtensionReturnType (typeof(string))] public class ExtExtension : MarkupExtension { [ConstructorArgument ("foo")] public Foo Foo { get; set; } public ExtExtension (Foo foo) { Foo = foo; } public override object ProvideValue (IServiceProvider provider) { return Foo.ToString(); } } public class Foo { } } 

When I launch the application, the following exception is thrown:

 System.NullReferenceException was unhandled Message=Object reference not set to an instance of an object. Source=System.Xaml StackTrace: at MS.Internal.Xaml.Runtime.ClrObjectRuntime.GetConverterInstance[TConverterBase](XamlValueConverter`1 converter) at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateObjectWithTypeConverter(ServiceProviderContext serviceContext, XamlValueConverter`1 ts, Object value) at MS.Internal.Xaml.Runtime.ClrObjectRuntime.CreateFromValue(ServiceProviderContext serviceContext, XamlValueConverter`1 ts, Object value, XamlMember property) at System.Xaml.XamlObjectWriter.Logic_CreateFromValue(ObjectWriterContext ctx, XamlValueConverter`1 typeConverter, Object value, XamlMember property, String targetName, IAddLineInfo lineInfo) at System.Xaml.XamlObjectWriter.Logic_ConvertPositionalParamsToArgs(ObjectWriterContext ctx) at System.Xaml.XamlObjectWriter.WriteEndMember() at System.Xaml.XamlWriter.WriteNode(XamlReader reader) at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlReader templateReader, XamlObjectWriter currentWriter) at System.Windows.FrameworkTemplate.LoadTemplateXaml(XamlObjectWriter objectWriter) at System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(DependencyObject container, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField) at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren) at System.Windows.StyleHelper.ApplyTemplateContent(UncommonField`1 dataField, DependencyObject container, FrameworkElementFactory templateRoot, Int32 lastChildIndex, HybridDictionary childIndexFromChildID, FrameworkTemplate frameworkTemplate) at System.Windows.FrameworkTemplate.ApplyTemplateContent(UncommonField`1 templateDataField, FrameworkElement container) at System.Windows.FrameworkElement.ApplyTemplate() at System.Windows.FrameworkElement.MeasureCore(Size availableSize) at System.Windows.UIElement.Measure(Size availableSize) at System.Windows.ContextLayoutManager.UpdateLayout() at System.Windows.UIElement.UpdateLayout() at System.Windows.Interop.HwndSource.SetLayoutSize() at System.Windows.Interop.HwndSource.set_RootVisualInternal(Visual value) at System.Windows.Interop.HwndSource.set_RootVisual(Visual value) at System.Windows.Window.SetRootVisual() at System.Windows.Window.SetRootVisualAndUpdateSTC() at System.Windows.Window.SetupInitialState(Double requestedTop, Double requestedLeft, Double requestedWidth, Double requestedHeight) at System.Windows.Window.CreateSourceWindow(Boolean duringShow) at System.Windows.Window.CreateSourceWindowDuringShow() at System.Windows.Window.SafeCreateWindowDuringShow() at System.Windows.Window.ShowHelper(Object booleanBox) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.DispatcherOperation.InvokeImpl() at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Windows.Threading.DispatcherOperation.Invoke() at System.Windows.Threading.Dispatcher.ProcessQueue() at System.Windows.Threading.Dispatcher.WndProcHook(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled) at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o) at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler) at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs) at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam) at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg) at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame) at System.Windows.Threading.Dispatcher.Run() at System.Windows.Application.RunDispatcher(Object ignore) at System.Windows.Application.RunInternal(Window window) at System.Windows.Application.Run(Window window) at System.Windows.Application.Run() at MarkupExtParam.App.Main() in d:\Docs\Projects\_Bugs\SubclassingBinding\obj\Debug\App.g.cs:line 0 at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() at System.Threading.ThreadHelper.ThreadStart_Context(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.ThreadHelper.ThreadStart() 

If I do not use a DataTemplate and cannot find <TextBlock Text="{my:Ext {StaticResource foo}}"/> outside, everything works fine.

I tried debugging using PDB with .NET Refelector (public sources do not seem to contain any inner classes), but to no avail because Reflector cannot create proper PDBs for highly optimized assemblies, so breakpoints do not work, most variables and arguments are not available, etc. I realized that the XAML parser is trying to bind a StaticResourceHolder (a subclass of StaticResourceExtension) to Foo and it fails (I can’t understand why this is happening).

Question: How to solve the problem? Maybe I'm just doing something wrong?

+4
source share
1 answer

The problem was solved by adding the following attribute to the Foo class:

 [TypeConverter(typeof(TypeConverter))] 

Obviously, in this case, an indication of the type converter becomes mandatory. If you need a different type of converter for the class, do not forget to call the basic methods (Convert *, CanConvert *). The way the TypeConverter attribute is TypeConverter to the constructor argument does not seem to exist.

+3
source

All Articles