select sln node in tree view externally

This commit is contained in:
Matt Parker
2025-08-17 16:09:43 +10:00
parent 179f2ab0e4
commit ae68b206db
4 changed files with 38 additions and 42 deletions

View File

@@ -5,7 +5,7 @@
<MudTreeView T="string" Dense="true" ExpandOnClick="true">
@foreach (var project in SolutionModel.AllProjects)
{
<ProjectProblemComponent ProjectModel="@project" SelectedFile="@SelectedFile" SelectedFileChanged="@SelectedFileChanged"/>
<ProjectProblemComponent ProjectModel="@project" OnFileSelected="@OnFileSelected" />
}
</MudTreeView>
</MudStack>
@@ -14,9 +14,6 @@
[Parameter, EditorRequired]
public SharpIdeSolutionModel SolutionModel { get; set; } = null!;
[Parameter, EditorRequired]
public SharpIdeFile SelectedFile { get; set; } = null!;
[Parameter]
public EventCallback<SharpIdeFile> SelectedFileChanged { get; set; }
public EventCallback<SharpIdeFile> OnFileSelected { get; set; }
}

View File

@@ -25,11 +25,8 @@
[Parameter, EditorRequired]
public SharpIdeProjectModel ProjectModel { get; set; } = null!;
[Parameter, EditorRequired]
public SharpIdeFile SelectedFile { get; set; } = null!;
[Parameter]
public EventCallback<SharpIdeFile> SelectedFileChanged { get; set; }
public EventCallback<SharpIdeFile> OnFileSelected { get; set; }
private ImmutableArray<Diagnostic> _diagnostics = [];
@@ -48,7 +45,7 @@
.Concat(ProjectModel.Folders.SelectMany(f => f.GetAllFiles()))
.Single(s => s.Path == diagnostic.Location.SourceTree?.GetMappedLineSpan(diagnostic.Location.SourceSpan).Path);
await SelectedFileChanged.InvokeAsync(file);
await OnFileSelected.InvokeAsync(file);
}
protected override async Task OnInitializedAsync()

View File

@@ -18,7 +18,7 @@
}
</style>
<MudTreeView T="ISharpIdeNode" Dense="true" ExpandOnClick="true">
<MudTreeView T="ISharpIdeNode" Dense="true" ExpandOnClick="true" SelectedValue="@SelectedNode" SelectedValueChanged="@SelectedNodeChanged">
<MudTreeViewItem T="ISharpIdeNode" TextTypo="Typo.body2" Expanded="true" Icon="@Icons.Material.Filled.Folder" IconColor="Color.Primary" Value="@SolutionModel" Text="@SolutionModel.Name">
@foreach (var folder in SolutionModel.Folders)
{
@@ -44,34 +44,14 @@
public SharpIdeSolutionModel SolutionModel { get; set; } = null!;
[Parameter, EditorRequired]
public SharpIdeFile SelectedFile { get; set; } = null!;
public ISharpIdeNode? SelectedNode { get; set; } = null!;
[Parameter]
public EventCallback<SharpIdeFile> SelectedFileChanged { get; set; }
public EventCallback<ISharpIdeNode?> SelectedNodeChanged { get; set; }
private MudMenu _contextMenuRef = null!;
private SharpIdeProjectModel? _contextMenuProject;
protected override async Task OnParametersSetAsync()
{
if (SelectedFile is null) return;
var parent = SelectedFile.Parent;
parent.Expanded = true;
while (parent is IChildSharpIdeNode childNode)
{
if (childNode is not IExpandableSharpIdeNode expandableNode) throw new InvalidOperationException("Parent node must implement IExpandableSharpIdeNode");
expandableNode.Expanded = true;
parent = childNode.Parent;
}
if (parent is not SharpIdeSolutionModel solutionModel) throw new InvalidOperationException("Parent node must be a SharpIdeSolutionModel");
solutionModel.Expanded = true;
}
private async Task InvokeSelectedFileChanged(SharpIdeFile file)
{
SelectedFile = file;
await SelectedFileChanged.InvokeAsync(file);
}
private MudTreeView<ISharpIdeNode> _treeViewRef = null!;
private async Task OpenProjectContextMenu(MouseEventArgs args, SharpIdeProjectModel project)
{
@@ -147,8 +127,7 @@
private RenderFragment GetFileFragment(SharpIdeFile file) =>
@<text>
<MudTreeViewItem T="ISharpIdeNode" Icon="@Icons.Custom.FileFormats.FileCode" TextTypo="Typo.body2" Text="@file.Name" Value="@file" OnClick="@(async () => await InvokeSelectedFileChanged(file))"/>
<MudTreeViewItem T="ISharpIdeNode" Icon="@Icons.Custom.FileFormats.FileCode" TextTypo="Typo.body2" Text="@file.Name" Value="@file"/>
</text>;
}

View File

@@ -1,10 +1,8 @@
@using Microsoft.Build.Tasks
@using SharpIDE.Application.Features.Analysis
@using SharpIDE.Application.Features.Analysis
@using SharpIDE.Application.Features.Build
@using SharpIDE.Application.Features.Events
@using SharpIDE.Application.Features.SolutionDiscovery
@using SharpIDE.Application.Features.SolutionDiscovery.VsPersistence
@using SharpIDE.Photino.Components.Problems
@using SharpIDE.Photino.Models
@inherits LayoutComponentBase
@@ -66,7 +64,7 @@
<MudDrawer @bind-Open="@_drawerOpen" Style="height: 100%" Width="400px" Fixed="false" Variant="@DrawerVariant.Persistent">
@if (_solutionFilePath is not null)
{
<SolutionExplorer @bind-SelectedFile="@_selectedFile" SolutionModel="@_solutionModel"/>
<SolutionExplorer @bind-SelectedNode="@_selectedNode" @bind-SelectedNode:after="@AfterSelectedNodeChanged" SolutionModel="@_solutionModel"/>
}
</MudDrawer>
<div class="d-flex justify-center align-center mud-height-full" style="flex-direction: row">
@@ -83,7 +81,7 @@
@if (_solutionFilePath is not null)
{
<DisplayNoneComponent Visible="@(_selectedBottomPanel is BottomPanelType.Problems)">
<ProblemsPanel SolutionModel="@_solutionModel" @bind-SelectedFile="@_selectedFile" />
<ProblemsPanel SolutionModel="@_solutionModel" OnFileSelected="@OnProblemSelected" />
</DisplayNoneComponent>
<DisplayNoneComponent Visible="@(_selectedBottomPanel is BottomPanelType.Run)">
<RunPanel SolutionModel="@_solutionModel"/>
@@ -107,6 +105,7 @@
private string? _solutionFilePath;
private SharpIdeSolutionModel? _solutionModel;
private ISharpIdeNode? _selectedNode;
private SharpIdeFile? _selectedFile;
private BottomPanelType? _selectedBottomPanel = null;
@@ -140,6 +139,31 @@
GlobalEvents.StartedRunningProject += OnStartedRunningProject;
}
private void OnProblemSelected(SharpIdeFile file)
{
_selectedFile = file;
_selectedNode = file;
var parent = _selectedFile.Parent;
parent.Expanded = true;
while (parent is IChildSharpIdeNode childNode)
{
if (childNode is not IExpandableSharpIdeNode expandableParent) throw new InvalidOperationException("Parent node must implement IExpandableSharpIdeNode");
expandableParent.Expanded = true;
parent = childNode.Parent;
}
if (parent is not SharpIdeSolutionModel solutionModel) throw new InvalidOperationException("Parent node must be a SharpIdeSolutionModel");
solutionModel.Expanded = true;
StateHasChanged();
}
private void AfterSelectedNodeChanged()
{
if (_selectedNode is SharpIdeFile file)
{
_selectedFile = file;
}
}
private async Task OnStartedRunningProject()
{
SelectBottomPanel(BottomPanelType.Run);
@@ -180,5 +204,4 @@
{
var dialogRef = await DialogService.ShowAsync<IdeSettingsDialog>("SharpIDE Settings", new DialogOptions { MaxWidth = MaxWidth.Medium, CloseButton = true });
}
}