mirror of
https://github.com/sourcegit-scm/sourcegit.git
synced 2024-12-23 20:47:25 -08:00
optimize<*>: use custom view locator instead of ContentControl.DataTemplates to avoid memory leak.
This commit is contained in:
parent
27d4dd5f64
commit
60e664ab26
9 changed files with 77 additions and 62 deletions
|
@ -160,26 +160,23 @@ namespace SourceGit.ViewModels {
|
|||
} else {
|
||||
page = ActivePage;
|
||||
page.Node = node;
|
||||
page.View = new Views.Repository() { DataContext = repo };
|
||||
page.Data = repo;
|
||||
}
|
||||
} else {
|
||||
page.Node = node;
|
||||
page.View = new Views.Repository() { DataContext = repo };
|
||||
page.Data = repo;
|
||||
}
|
||||
|
||||
ActivePage = page;
|
||||
}
|
||||
|
||||
private void CloseRepositoryInTab(LauncherPage page) {
|
||||
if (page.Node.IsRepository) {
|
||||
var repo = Preference.FindRepository(page.Node.Id);
|
||||
if (repo != null) {
|
||||
if (page.Data is Repository repo) {
|
||||
Commands.AutoFetch.RemoveRepository(repo.FullPath);
|
||||
repo.Close();
|
||||
}
|
||||
}
|
||||
|
||||
page.View = null;
|
||||
page.Data = null;
|
||||
}
|
||||
|
||||
private LauncherPage _activePage = null;
|
||||
|
|
|
@ -8,9 +8,9 @@ namespace SourceGit.ViewModels {
|
|||
set => SetProperty(ref _node, value);
|
||||
}
|
||||
|
||||
public object View {
|
||||
get => _view;
|
||||
set => SetProperty(ref _view, value);
|
||||
public object Data {
|
||||
get => _data;
|
||||
set => SetProperty(ref _data, value);
|
||||
}
|
||||
|
||||
public AvaloniaList<Models.Notification> Notifications {
|
||||
|
@ -25,12 +25,12 @@ namespace SourceGit.ViewModels {
|
|||
Bookmark = 0,
|
||||
IsRepository = false,
|
||||
};
|
||||
_view = new Views.Welcome() { DataContext = new Welcome() };
|
||||
_data = new Welcome();
|
||||
}
|
||||
|
||||
public LauncherPage(RepositoryNode node, Repository repo) {
|
||||
_node = node;
|
||||
_view = new Views.Repository() { DataContext = repo };
|
||||
_data = repo;
|
||||
}
|
||||
|
||||
public override string GetId() {
|
||||
|
@ -48,6 +48,6 @@ namespace SourceGit.ViewModels {
|
|||
}
|
||||
|
||||
private RepositoryNode _node = null;
|
||||
private object _view = null;
|
||||
private object _data = null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Media;
|
||||
using Avalonia.VisualTree;
|
||||
using System;
|
||||
|
@ -208,11 +207,6 @@ namespace SourceGit.Views {
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnUnloaded(RoutedEventArgs e) {
|
||||
base.OnUnloaded(e);
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
private void OnCommitDataGridLayoutUpdated(object sender, EventArgs e) {
|
||||
commitGraph.InvalidateVisual();
|
||||
}
|
||||
|
|
|
@ -223,8 +223,8 @@
|
|||
</Border>
|
||||
</Grid>
|
||||
|
||||
<!-- Page container -->
|
||||
<ContentControl Grid.Row="1" Background="{DynamicResource Brush.ToolBar}" Content="{Binding ActivePage.View}"/>
|
||||
<!-- Page body -->
|
||||
<v:LauncherBody Grid.Row="1" Background="{DynamicResource Brush.ToolBar}" Data="{Binding ActivePage.Data}"/>
|
||||
|
||||
<!-- Popup container -->
|
||||
<Grid Grid.Row="1" x:Name="popupContainer" Margin="0,36,0,0" ClipToBounds="True" IsVisible="{Binding ActivePage.Popup, Converter={x:Static ObjectConverters.IsNotNull}}">
|
||||
|
|
|
@ -23,6 +23,34 @@ namespace SourceGit.Views {
|
|||
}
|
||||
}
|
||||
|
||||
public class LauncherBody : Border {
|
||||
public static readonly StyledProperty<object> DataProperty =
|
||||
AvaloniaProperty.Register<LauncherBody, object>(nameof(Data), false);
|
||||
|
||||
public object Data {
|
||||
get => GetValue(DataProperty);
|
||||
set => SetValue(DataProperty, value);
|
||||
}
|
||||
|
||||
protected override Type StyleKeyOverride => typeof(Border);
|
||||
|
||||
static LauncherBody() {
|
||||
DataProperty.Changed.AddClassHandler<LauncherBody>((body, ev) => {
|
||||
var data = body.Data;
|
||||
|
||||
if (data == null) {
|
||||
body.Child = null;
|
||||
} else if (data is ViewModels.Welcome) {
|
||||
body.Child = new Welcome { DataContext = data };
|
||||
} else if (data is ViewModels.Repository) {
|
||||
body.Child = new Repository { DataContext = data };
|
||||
} else {
|
||||
body.Child = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Launcher : Window, Models.INotificationReceiver {
|
||||
public Launcher() {
|
||||
DataContext = new ViewModels.Launcher();
|
||||
|
|
|
@ -447,25 +447,7 @@
|
|||
<Button Grid.Column="3" Classes="flat" FontWeight="Regular" Content="{DynamicResource Text.Repository.Abort}" Height="20" Padding="8,0" Margin="4,0" Command="{Binding AbortMerge}"/>
|
||||
</Grid>
|
||||
|
||||
<ContentControl Grid.Row="1" Content="{Binding SelectedView}">
|
||||
<ContentControl.DataTemplates>
|
||||
<DataTemplate DataType="vm:Histories">
|
||||
<v:Histories/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="vm:WorkingCopy">
|
||||
<v:WorkingCopy/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="vm:StashesPage">
|
||||
<v:StashesPage/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate DataType="x:Double">
|
||||
<Border/>
|
||||
</DataTemplate>
|
||||
</ContentControl.DataTemplates>
|
||||
</ContentControl>
|
||||
<v:RepositorySubView Grid.Row="1" Data="{Binding SelectedView}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
|
@ -1,11 +1,45 @@
|
|||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls.Primitives;
|
||||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using SourceGit.ViewModels;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace SourceGit.Views {
|
||||
public class RepositorySubView : Border {
|
||||
public static readonly StyledProperty<object> DataProperty =
|
||||
AvaloniaProperty.Register<RepositorySubView, object>(nameof(Data), false);
|
||||
|
||||
public object Data {
|
||||
get => GetValue(DataProperty);
|
||||
set => SetValue(DataProperty, value);
|
||||
}
|
||||
|
||||
protected override Type StyleKeyOverride => typeof(Border);
|
||||
|
||||
static RepositorySubView() {
|
||||
DataProperty.Changed.AddClassHandler<RepositorySubView>((view, ev) => {
|
||||
var data = view.Data;
|
||||
|
||||
if (data == null) {
|
||||
view.Child = null;
|
||||
} else if (data is ViewModels.Histories) {
|
||||
view.Child = new Histories { DataContext = data };
|
||||
} else if (data is ViewModels.WorkingCopy) {
|
||||
view.Child = new WorkingCopy { DataContext = data };
|
||||
} else if (data is ViewModels.StashesPage) {
|
||||
view.Child = new StashesPage { DataContext = data };
|
||||
} else {
|
||||
view.Child = null;
|
||||
}
|
||||
|
||||
GC.Collect();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public partial class Repository : UserControl {
|
||||
public Repository() {
|
||||
InitializeComponent();
|
||||
|
|
|
@ -1,16 +1,9 @@
|
|||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using System;
|
||||
|
||||
namespace SourceGit.Views {
|
||||
public partial class StashesPage : UserControl {
|
||||
public StashesPage() {
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnUnloaded(RoutedEventArgs e) {
|
||||
base.OnUnloaded(e);
|
||||
GC.Collect();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ using Avalonia.Controls;
|
|||
using Avalonia.Input;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.VisualTree;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace SourceGit.Views {
|
||||
|
@ -11,18 +10,6 @@ namespace SourceGit.Views {
|
|||
InitializeComponent();
|
||||
}
|
||||
|
||||
protected override void OnUnloaded(RoutedEventArgs e) {
|
||||
var vm = DataContext as ViewModels.WorkingCopy;
|
||||
vm.SelectedStagedChange = null;
|
||||
vm.SelectedStagedTreeNode = null;
|
||||
vm.SelectedUnstagedChange = null;
|
||||
vm.SelectedUnstagedTreeNode = null;
|
||||
vm.SetDetail(null, false);
|
||||
|
||||
base.OnUnloaded(e);
|
||||
GC.Collect();
|
||||
}
|
||||
|
||||
private void ViewAssumeUnchanged(object sender, RoutedEventArgs e) {
|
||||
var repoPage = this.FindAncestorOfType<Repository>();
|
||||
if (repoPage != null) {
|
||||
|
|
Loading…
Reference in a new issue