{"record":{"id":"b48b9885db724a01","repo":"stride3d/stride","slug":"a-part-named-part-loggridview-must-be-present-in-the","errorCode":null,"errorMessage":"A part named 'PART_LogGridView' must be present in the ControlTemplate, and must be of type 'DataGridControl'.","messagePattern":"A part named 'PART_LogGridView' must be present in the ControlTemplate, and must be of type 'DataGridControl'\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.Core.Assets.Editor/View/Controls/GridLogViewer.cs","lineNumber":158,"sourceCode":"\n        /// <summary>\n        /// Gets or sets whether the log viewer should display fatal messages.\n        /// </summary>\n        public bool ShowStacktrace { get { return (bool)GetValue(ShowStacktraceProperty); } set { SetValue(ShowStacktraceProperty, value); } }\n\n        /// <summary>\n        /// Gets or sets the session to use to select an asset related to a log message.\n        /// </summary>\n        public SessionViewModel Session { get { return (SessionViewModel)GetValue(SessionProperty); } set { SetValue(SessionProperty, value); } }\n\n        /// <inheritdoc/>\n        public override void OnApplyTemplate()\n        {\n            base.OnApplyTemplate();\n\n            logGridView = GetTemplateChild(\"PART_LogGridView\") as DataGridEx;\n            if (logGridView == null)\n                throw new InvalidOperationException(\"A part named 'PART_LogGridView' must be present in the ControlTemplate, and must be of type 'DataGridControl'.\");\n\n            logGridView.MouseDoubleClick += GridMouseDoubleClick;\n\n            // We may have a bunch of messages appended before the logGridView was ready, let's present them now that it is \n            ApplyFilters();\n        }\n\n        private void GridMouseDoubleClick(object sender, MouseButtonEventArgs e)\n        {\n            if (Session == null)\n                return;\n\n            var logMessage = logGridView.SelectedItem as AssetSerializableLogMessage;\n            if (logMessage != null && !string.IsNullOrEmpty(logMessage.AssetUrl))\n            {\n                var asset = Session.GetAssetById(logMessage.AssetId);\n                if (asset != null)\n                    Session.ActiveAssetView.SelectAssetCommand.Execute(asset);","sourceCodeStart":140,"sourceCodeEnd":176,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.Core.Assets.Editor/View/Controls/GridLogViewer.cs#L140-L176","documentation":"GridLogViewer.OnApplyTemplate retrieves its named template part PART_LogGridView and requires it to be a DataGridEx. If the applied ControlTemplate lacks that part or it is a different type, logGridView stays null and an InvalidOperationException is thrown, because the viewer cannot wire double-click handling and filters without the grid.","triggerScenarios":"Applying a custom Style/ControlTemplate to GridLogViewer that omits the PART_LogGridView part, names it differently, or declares it as a type other than DataGridEx.","commonSituations":"Re-templating the control for styling and forgetting the template-part contract; renaming the part in XAML; using a DataGrid instead of DataGridEx in a custom template.","solutions":["Add <stride:DataGridEx x:Name=\"PART_LogGridView\"/> to the custom ControlTemplate for GridLogViewer","Ensure the part's exact name 'PART_LogGridView' and type DataGridEx match TemplatePart contract","Remove the custom template so the default one applies"],"exampleFix":"// before\n<Style TargetType=\"controls:GridLogViewer\">\n  <Setter Property=\"Template\">\n    <Setter.Value>\n      <ControlTemplate TargetType=\"controls:GridLogViewer\">\n        <DataGrid x:Name=\"LogGrid\"/>\n      </ControlTemplate>\n    </Setter.Value>\n  </Setter>\n</Style>\n// after\n<ControlTemplate TargetType=\"controls:GridLogViewer\">\n  <controls:DataGridEx x:Name=\"PART_LogGridView\"/>\n</ControlTemplate>","handlingStrategy":"try-catch","validationCode":"var part = logViewer.Template.FindName(\"PART_LogGridView\", logViewer) as DataGridEx;\nif (part == null) throw new InvalidOperationException(\"Template must contain a DataGridEx named PART_LogGridView\");","typeGuard":"static bool HasValidLogTemplate(GridLogViewer v) => v.FindVisualChildOfType<DataGridEx>(x => x.Name == \"PART_LogGridView\") != null;","tryCatchPattern":"try { logViewer.ApplyTemplate(); }\ncatch (InvalidOperationException ex) { log.Error(\"GridLogViewer template missing PART_LogGridView\", ex); }","preventionTips":["Respect TemplatePart attributes when re-templating custom controls","Keep the exact PART_ names and part types from the default template","Smoke-test custom styles by applying them in a UI test"],"tags":["wpf","control-template","template-part"],"backgroundTag":"missing-required-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}