2009-07-16 12 views
10

Używam następujący kod dynamicznie dodawać kolumny do mojego GridView:dynamicznie dodawane DataTemplate - StaticResource dla Converter nie można znaleźć

public void AddGridViewColumns() 
{ 
    GridView view = (GridView)_myListView.View; 
    GridViewColumn column = BuildGridViewColumn(1); 
    view.Columns.Add(column); 
} 

public virtual GridViewColumn BuildGridViewColumn(int blockIndex) 
{ 
    string templateXaml = string.Format(
     @"<DataTemplate 
      xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" 
      xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" 
      xmlns:local=""clr-namespace:Pse.MyTest;assembly=MyTest""> 
      <DataTemplate.Resources> 
       <local:BlockToBrushConverter 
        x:Key=""_blockToBrushConverter"" /> 
      </DataTemplate.Resources> 
      <TextBlock 
       Style=""{{StaticResource _gridViewCenterItemStyle}}"" 
       Text=""{{Binding Path=Block{0}.ConditionLabel}}"" 
       Foreground=""{{Binding Path=Block{0}, Converter={{StaticResource _blockToBrushConverter}}}}"" /> 
     </DataTemplate>", 
     blockIndex); 
    System.Diagnostics.Debug.Print(templateXaml); 
    GridViewColumn column = new GridViewColumn(); 
    column.Header = string.Format("Block {0}", blockIndex); 
    column.CellTemplate = (DataTemplate)XamlReader.Parse(templateXaml); 
    return column; 
} 

Wyniki Debug.Print w:

<DataTemplate 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:Pse.MyTest;assembly=MyTest"> 
    <DataTemplate.Resources> 
     <local:BlockToBrushConverter 
      x:Key="_blockToBrushConverter" /> 
    </DataTemplate.Resources> 
    <TextBlock 
     Style="{StaticResource _gridViewCenterItemStyle}" 
     Text="{Binding Path=Block1.ConditionLabel}" 
     Foreground="{Binding Path=Block1, Converter={StaticResource _blockToBrushConverter}}" /> 
</DataTemplate> 

Po uruchomieniu mówi, że nie może znaleźć _blockToBrushConverter.

Wyjątkiem jest:

System.Windows.Markup.XamlParseException was unhandled 
    Message="Cannot find resource named '{_blockToBrushConverter}'. Resource names are case sensitive. Error at object 'System.Windows.Data.Binding' in markup file 'MyTest;component/SetupWindowDictionary.xaml' Line 23 Position 13." 
    Source="PresentationFramework" 
    LineNumber=23 
    LinePosition=13 
    NameContext="Foreground" 

Jeśli usunąć atrybut ForeColor, XAML analizuje dobrze (i uzyskać oczekiwane rezultaty). Wygląda na to, że należy włączyć konwerter w DateTemplate.Resources powinien zagwarantować, że zostanie znaleziony, ale z jakiegoś powodu tak nie jest.

Próbowałem również przenieść deklarację dla mojego zasobu konwertera wyżej w drzewie (do poziomu okna), ale to też nie działało. Wygląda na to, że potrafi znaleźć "_gridViewCenterItemStyle", ale z jakiegoś powodu odmawia znalezienia konwertera.

Wszelkie pomysły bardzo doceniane.


Oto cała wyjątek z ślad stosu w przypadku pomaga:

System.Windows.Markup.XamlParseException was unhandled 
    Message="Cannot find resource named '{_blockToBrushConverter}'. Resource names are case sensitive. Error at object 'System.Windows.Data.Binding' in markup file 'MyTest;component/SetupWindowDictionary.xaml' Line 23 Position 13." 
    Source="PresentationFramework" 
    LineNumber=23 
    LinePosition=13 
    NameContext="Foreground" 
    StackTrace: 
     at System.Windows.Markup.XamlParseException.ThrowException(String message, Exception innerException, Int32 lineNumber, Int32 linePosition, Uri baseUri, XamlObjectIds currentXamlObjectIds, XamlObjectIds contextXamlObjectIds, Type objectType) 
     at System.Windows.Markup.XamlParseException.ThrowException(ParserContext parserContext, Int32 lineNumber, Int32 linePosition, String message, Exception innerException) 
     at System.Windows.Markup.BamlRecordReader.ThrowExceptionWithLine(String message, Exception innerException) 
     at System.Windows.Markup.BamlRecordReader.ThrowException(String id, String parameter) 
     at System.Windows.StaticResourceExtension.ProvideValueInternal(IBamlReader bamlReader, Object targetObject, Object targetProperty, Boolean allowDeferredReference) 
     at System.Windows.StaticResourceExtension.ProvideValue(IServiceProvider serviceProvider) 
     at System.Windows.Markup.BamlRecordReader.ProvideValueFromMarkupExtension(MarkupExtension markupExtension, Object obj, Object member) 
     at System.Windows.Markup.BamlRecordReader.BaseReadOptimizedMarkupExtension(Object element, Int16 attributeId, PropertyDefinition propertyDefinition, Object value) 
     at System.Windows.Markup.BamlRecordReader.ReadPropertyWithStaticResourceIdRecord(BamlPropertyWithStaticResourceIdRecord bamlPropertyWithStaticResourceIdRecord) 
     at System.Windows.Markup.BamlRecordReader.ReadRecord(BamlRecord bamlRecord) 
     at System.Windows.StyleHelper.LoadOptimizedTemplateContent(DependencyObject container, ParserContext parserContext, OptimizedTemplateContent optimizedTemplateContent, FrameworkTemplate frameworkTemplate, IComponentConnector componentConnector, IStyleConnector styleConnector, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField) 
     at System.Windows.FrameworkTemplate.LoadContent(DependencyObject container, List`1 affectedChildren, UncommonField`1 templatedNonFeChildrenField) 
     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.Controls.GridViewRowPresenter.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.Border.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.Control.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint) 
     at System.Windows.Controls.ItemsPresenter.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint) 
     at System.Windows.Controls.ScrollContentPresenter.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.DockPanel.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.Grid.MeasureCell(Int32 cell, Boolean forceInfinityV) 
     at System.Windows.Controls.Grid.MeasureCellsGroup(Int32 cellsHead, Size referenceSize, Boolean ignoreDesiredSizeU, Boolean forceInfinityV) 
     at System.Windows.Controls.Grid.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.ScrollViewer.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.Border.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.Control.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.Controls.Grid.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at MS.Internal.Helper.MeasureElementWithSingleChild(UIElement element, Size constraint) 
     at System.Windows.Controls.ContentPresenter.MeasureOverride(Size constraint) 
     at System.Windows.FrameworkElement.MeasureCore(Size availableSize) 
     at System.Windows.UIElement.Measure(Size availableSize) 
     at System.Windows.ContextLayoutManager.UpdateLayout() 
     at System.Windows.ContextLayoutManager.UpdateLayoutCallback(Object arg) 
     at System.Windows.Media.MediaContext.InvokeOnRenderCallback.DoWork() 
     at System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks() 
     at System.Windows.Media.MediaContext.RenderMessageHandlerCore(Object resizedCompositionTarget) 
     at System.Windows.Media.MediaContext.RenderMessageHandler(Object resizedCompositionTarget) 
     at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Boolean isSingleParameter) 
     at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) 
     at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) 
     at System.Windows.Threading.DispatcherOperation.InvokeImpl() 
     at System.Windows.Threading.DispatcherOperation.InvokeInSecurityContext(Object state) 
     at System.Threading.ExecutionContext.runTryCode(Object userData) 
     at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData) 
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) 
     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, Boolean isSingleParameter) 
     at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) 
     at System.Windows.Threading.Dispatcher.WrappedInvoke(Delegate callback, Object args, Boolean isSingleParameter, Delegate catchHandler) 
     at System.Windows.Threading.Dispatcher.InvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Boolean isSingleParameter) 
     at System.Windows.Threading.Dispatcher.Invoke(DispatcherPriority priority, Delegate method, Object arg) 
     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 Pse.TestExperiment.App.Main() in C:\Documents and Settings\Daniel Manes\My Documents\Projects\Cmd21\Team Map Experiment 2\Solution\TestExperiment\obj\Debug\App.g.cs:line 0 
     at System.AppDomain._nExecuteAssembly(Assembly 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.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 

EDIT:

Problem rozwiązany: zrobiłem wyszukiwania poprzez całego mojego projektu i zauważyłem, że mieliśmy dodatkowa kopia deklaracji zasobu BlockToBrushConverter z tym samym x: Wpisz jeden z moich słowników zasobów. Po wyeliminowaniu duplikacji problem zniknął.

+0

Mam wygenerowane DataTemple bardzo podobne do twojego wydruku debugowania - po załadowaniu go, otrzymuję "Załączniki zasobów nieruchomości nie znaleziono w typ DataTemplate" choć moja przestrzeń nazw zawiera i reszta z moich xaml są identyczne z wyjątkiem kontrole – jchristof

Odpowiedz

6

Kiedy ktoś spojrzy na to pytanie pewnego dnia, okazuje się, że kod, który przedstawiłem na górze tego pytania, faktycznie działa. Błąd było to, że miałem następującą deklarację gdzie indziej w moim XAML:

<local:BlockToBrushConverter 
    x:Key="_blockToBrushConverter" /> 

wierzę to powielanie uniemożliwił zasobu z zadeklarowana lokalnie dla dynamicznego DataTemplate (nie może utworzyć zasób o tej samej nazwie dwa razy w ciągu w tym samym kontekście).

Jedną z rzeczy, które są dla mnie nierozwiązane, jest to, dlaczego niektóre StaticResources muszą być zadeklarowane lokalnie, podczas gdy inne (takie jak _gridViewCenterItemStyle StaticResource) mogą być zadeklarowane wyżej w drzewie (na przykład na poziomie okna) bez problemu.

Powiązane problemy