2009-07-16 7 views
10

J'utilise le code suivant pour ajouter dynamiquement des colonnes à mon GridView:ajouté Dynamiquement DataTemplate - StaticResource pour Converter ne peut être trouvé

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

Les résultats Debug.Print dans:

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

Quand je l'exécute, il dit qu'il ne peut pas trouver _blockToBrushConverter.

L'exception est:

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" 

Si je supprime l'attribut ForeColor, le XAML parse très bien (et j'obtenir les résultats escomptés). Il semble que l'inclusion du convertisseur dans DateTemplate.Resources devrait garantir qu'il serait trouvé, mais pour une raison quelconque, il ne l'est pas.

J'ai également essayé de déplacer la déclaration de ma ressource de convertisseur plus haut dans l'arbre (au niveau de la fenêtre), mais cela n'a pas fonctionné non plus. Il semble être capable de trouver "_gridViewCenterItemStyle", mais pour une raison quelconque, il refuse de trouver le convertisseur.

Toutes les idées grandement appréciées.


est ici l'exception entière avec trace de la pile dans le cas où il aide:

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:

Problème résolu: Je fait une recherche dans mon projet entier et remarqué que j'avais une copie supplémentaire de la déclaration de ressource BlockToBrushConverter avec le même x: Clé dans un de mes dictionnaires de ressources. Une fois que j'ai éliminé la duplication, le problème a disparu.

+0

J'ai un DataTemple généré très similaire à votre impression de débogage - quand je le charge, j'obtiens "La propriété attachable Ressources n'a pas été trouvée dans le type DataTemplate" bien que mon espace de noms inclue et le reste de mon xaml sont identiques sauf pour les contrôles – jchristof

Répondre

6

Juste au cas où quelqu'un d'autre jette un coup d'oeil à cette question un jour, il s'avère que le code que j'ai présenté en haut de cette question fonctionne réellement. Le bug est que j'avais d'ailleurs la déclaration suivante dans mon XAML:

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

Je crois que ce double emploi a empêché la ressource d'être déclaré localement pour la DataTemplate dynamique (il ne pouvait pas créer une ressource avec le même nom deux fois dans le même contexte). Une chose qui n'est pas résolue pour moi est pourquoi certaines ressources statiques doivent être déclarées localement, alors que d'autres (comme le _gridViewCenterItemStyle StaticResource) peuvent être déclarées plus haut dans l'arbre (comme au niveau de la fenêtre) sans problème.

Questions connexes