4

問題を最小限のコードに単純化した後でも、何が原因であるのか理解できませんNullReferenceException

新しいWPFアプリケーション「MarkupExtParam」を作成します。コードを置き換えます:

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 { }
}

アプリケーションを実行すると、次の例外がスローされます。

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()

DataTemplateを使用せずに<TextBlock Text="{my:Ext {StaticResource foo}}"/>外部に配置すると、すべて正常に機能します。

.NET Refelectorで生成されたPDB(パブリックソースには内部クラスが含まれていないようです)を使用してデバッグを試みましたが、Reflectorは高度に最適化されたアセンブリ用の適切なPDBを生成できないため、ブレークポイントが機能せず、ほとんどの変数が機能しません。 XAMLパーサーがStaticResourceHolder(StaticResourceExtensionのサブクラス)をFooに割り当てようとして失敗することを理解しました(ただし、なぜ発生するのか理解できません)。

質問:問題を解決するにはどうすればよいですか?多分私は何か間違ったことをしているだけですか?

4

1 に答える 1

3

Fooクラスに次の属性を追加することで解決された問題:

[TypeConverter(typeof(TypeConverter))]

この場合、明らかに型コンバーターの指定が必須になります。クラスに別の型コンバーターが必要な場合は、基本メソッド (Convert*、CanConvert*) を呼び出すことを忘れないでください。コンストラクターの引数に属性を適用する方法TypeConverterは存在しないようです。

于 2012-12-08T15:52:33.907 に答える