DYN-10717 Fix the Save/Save As menu items hardcoded - #17255
DYN-10717 Fix the Save/Save As menu items hardcoded#17255edwin-vasquez-ucaldas wants to merge 8 commits into
Conversation
There was a problem hiding this comment.
See the ticket for this pull request: https://jira.autodesk.com/browse/DYN-10717
There was a problem hiding this comment.
Pull request overview
This PR addresses a WPF UI bug in DynamoCoreWpf where the Save / Save As menu items were hardcoded as disabled in DynamoView.xaml, leaving them unusable for newly created (unsaved) workspaces (while keyboard shortcuts still worked via CanExecute).
Changes:
- Removed hardcoded
IsEnabled="False"from the Save / Save AsMenuItems inDynamoView.xaml. - Removed code-behind logic that imperatively re-enabled those menu items when certain events fired.
- Trimmed trailing whitespace in a generated XML documentation file.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs | Removes imperative enablement of Save/Save As menu items from event handlers (but currently leaves them out of the broader enable/disable flow). |
| src/DynamoCoreWpf/Views/Core/DynamoView.xaml | Removes hardcoded disabled state for Save/Save As menu items so WPF can derive enablement from other mechanisms. |
| doc/distrib/xml/en-US/DSCoreNodes.xml | Whitespace-only cleanup in XML documentation output. |
Comments suppressed due to low confidence (1)
src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs:472
OnWorkspaceOpenedstill re-enables Export and the shortcut bar Save button, but it no longer re-enables the Save/Save As menu items. If those menu items were disabled viaOnEnableShortcutBarItems(false)(e.g., when Start Page is shown), opening a workspace may not restore them. Re-enabling them here keeps behavior consistent with the other UI elements this handler restores.
private void OnWorkspaceOpened(WorkspaceModel workspace)
{
if (!(exportMenu is null))
{
exportMenu.IsEnabled = true;
}
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
test/DynamoCoreWpfTests/DynamoViewTests.cs:162
- This test flips the global static
DynamoModel.IsTestModebut doesn’t guarantee it’s restored if an assertion fails, which can cascade into unrelated failures in later tests (TearDown doesn’t resetIsTestMode). Capture the original value and restore it in afinallyblock.
DynamoModel.IsTestMode = false;
ViewModel.CloseHomeWorkspaceCommand.Execute(null);
DynamoModel.IsTestMode = true;
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
src/DynamoCoreWpf/Views/Core/DynamoView.xaml.cs:440
- Save/Save As MenuItems are no longer disabled when DynamoViewModel raises RequestEnableShortcutBarItems(false) (the handler now only disables export/shortcut bar). Since the Save commands' CanExecute predicates are currently hard-coded to always return true (DynamoViewModel.cs:3248, 3372) and Dynamo.UI.Commands.DelegateCommand does not auto-requery, the Save menu items will remain enabled even in UI-lock states like Guided Tour start (GuidesManager.cs:166). Consider moving the enable/disable logic into the commands' CanExecute (e.g., return !GuideFlowEvents.IsAnyGuideActive) and calling RaiseCanExecuteChanged when that state toggles, so both menu items and keybindings behave consistently.
private void DynamoViewModel_RequestEnableShortcutBarItems(bool enable)
{
if (!(exportMenu is null))
{
exportMenu.IsEnabled = enable;
src/DynamoCoreWpf/Views/Core/DynamoView.xaml:358
- The hardcoded IsEnabled="False" removal makes Save/Save As enabled by default, but the PR description/release note says enablement should be driven by a real CanExecute predicate. Currently both CanShowSaveDialogIfNeededAndSaveResultCommand and CanShowSaveDialogAndSaveResult always return true (DynamoViewModel.cs:3248, 3372), so enablement is effectively unconditional and won’t respect any intentional UI-disable state (e.g., Guided Tour). Implementing a state-based CanExecute (and raising CanExecuteChanged when it changes) would align behavior with the PR intent.
<MenuItem Name="saveThisButton"
Command="{Binding ShowSaveDialogIfNeededAndSaveResultCommand}"
Header="{x:Static p:Resources.DynamoViewFileMenuSave}"
InputGestureText="Ctrl + S" />
<MenuItem Name="saveButton"
…m AddHomeWorkspace() and the tab-close-creates-new-workspace path too
…red CanExecute, gated on guided tour, Start Page, and workspace dirty state
There was a problem hiding this comment.
🟢 Ready to approve
The changes consistently centralize Save/Save As enablement in CanExecute, remove conflicting imperative UI toggles, and include targeted regression tests for the reported scenarios.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
- Files reviewed: 6/7 changed files
- Comments generated: 0 new
- Review effort level: Low
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
… of the whitespace
There was a problem hiding this comment.
🟡 Not ready to approve
New code introduces a couple of avoidable null-reference risks by invoking RaiseCanExecuteChanged() without null-checks on public settable command properties.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
Comments suppressed due to low confidence (2)
src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs:3302
SetGuidedTourActivecallsRaiseCanExecuteChanged()on the Save/Save As commands without null-checks. These commands are public settable properties, so a null assignment (by external code or future changes) would cause a crash when a guided tour starts/ends. Use null-conditional invocations to keep this gating method robust.
internal void SetGuidedTourActive(bool isActive)
{
isGuidedTourActive = isActive;
ShowSaveDialogIfNeededAndSaveResultCommand.RaiseCanExecuteChanged();
ShowSaveDialogAndSaveResultCommand.RaiseCanExecuteChanged();
src/DynamoCoreWpf/ViewModels/Core/DynamoViewModel.cs:1338
SaveCommandsTrackedWorkspace_PropertyChangedcallsShowSaveDialogIfNeededAndSaveResultCommand.RaiseCanExecuteChanged()without a null-check, butShowSaveDialogIfNeededAndSaveResultCommandis a public settable property (PublicAPI.Shipped). If it is ever unset (e.g., by external consumers or during future refactors), this handler will throw and potentially break workspace switching / dirty tracking. Use a null-conditional invocation here to keep the handler resilient.
This issue also appears on line 3298 of the same file.
private void SaveCommandsTrackedWorkspace_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if (e.PropertyName == nameof(WorkspaceModel.HasUnsavedChanges))
ShowSaveDialogIfNeededAndSaveResultCommand.RaiseCanExecuteChanged();
- Files reviewed: 6/6 changed files
- Comments generated: 0 new
- Review effort level: Low
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
|
|
@edwin-vasquez-ucaldas seems that there are two regresssions also update the branch |
There was a problem hiding this comment.
🟢 Ready to approve
The change removes the root cause (hardcoded disabled UI), replaces it with consistent command-based CanExecute logic, and includes targeted regression tests for the reported scenarios.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 0 new
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.
|
Thanks @RobertGlobant20, yes there are 2 executions for the Smoke Tests, because the # 453 was failing, I just send a new Rebuild for it. |
There was a problem hiding this comment.
🟢 Ready to approve
The change cleanly centralizes Save/Save As enablement in CanExecute, removes conflicting imperative UI toggles, and adds targeted regression tests for the reported scenarios.
This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.
Review details
- Files reviewed: 6/6 changed files
- Comments generated: 0 new
- Review effort level: Lite
We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.





Purpose
The Save/Save As menu items are hardcoded
IsEnabled="False"in XAML, and no code path re-enables them for freshly created (as opposed to opened) workspaces.The MenuItems don't use
CanExecuteat all in DynamoView.xaml.IsEnabled="False"is a literal, not a binding — WPF never re-derives it from the command'sCanExecute(which, per DynamoViewModel.cs:3248 and :3372, always returns true anyway).The only two things that flip
IsEnabledback totrueare event handlers in DynamoView.xaml.cs:OnWorkspaceOpened— wired to Model.WorkspaceOpened += OnWorkspaceOpenedDynamoViewModel_RequestEnableShortcutBarItems— wired to RequestEnableShortcutBarItemsWorkspaceOpenedonly fires fromOpenWorkspace()(DynamoModel.cs) for example opening an existing file. It does not fire fromAddHomeWorkspace(), which is what creates the blank/default workspace at Dynamo startup, and is also the pattern used when a tab is closed and a fresh empty workspace takes its place.Ctrl+S bypasses the bug because
KeyBindingin XAML only checksCommand.CanExecute(hardcoded true), neverMenuItem.IsEnabled, completely independent mechanisms bound to the same command.Before fix

After fix

Declarations
Check these if you believe they are true
Release Notes
Remove the
hardcoded IsEnabled="False"and drive enablement through a realCanExecutepredicate, removing the redundant imperative toggle mechanism entirely. It fixes the whole class of bug rather than patching another missed call site.Reviewers
@jasonstratton @RobertGlobant20
@jnealb