refactor: using ListBox instead of DataGrid for commit list and remove dependency of Avalonia.Controls.DataGrid

This commit is contained in:
leo 2024-08-28 10:02:14 +08:00
parent 7776cda475
commit bd6228bb26
No known key found for this signature in database
6 changed files with 186 additions and 213 deletions

View file

@ -22,7 +22,6 @@
<Application.Styles> <Application.Styles>
<FluentTheme /> <FluentTheme />
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
<StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" /> <StyleInclude Source="avares://AvaloniaEdit/Themes/Fluent/AvaloniaEdit.xaml" />
<StyleInclude Source="/Resources/Styles.axaml"/> <StyleInclude Source="/Resources/Styles.axaml"/>
</Application.Styles> </Application.Styles>

View file

@ -1328,22 +1328,6 @@
<Setter Property="Opacity" Value="1"/> <Setter Property="Opacity" Value="1"/>
</Style> </Style>
<Style Selector="DataGrid /template/ Rectangle#PART_ColumnHeadersAndRowsSeparator">
<Setter Property="IsVisible" Value="False"/>
</Style>
<Style Selector="DataGridCell">
<Setter Property="MinHeight" Value="24"/>
</Style>
<Style Selector="DataGridCell:focus /template/ Grid#FocusVisual">
<Setter Property="IsVisible" Value="False"/>
</Style>
<Style Selector="DataGridRow /template/ Rectangle#PART_BottomGridLine">
<Setter Property="IsVisible" Value="False"/>
</Style>
<Style Selector="DataGridRow /template/ DataGridDetailsPresenter#PART_DetailsPresenter">
<Setter Property="IsVisible" Value="False"/>
</Style>
<Style Selector="NumericUpDown"> <Style Selector="NumericUpDown">
<Style Selector="^ /template/ ButtonSpinner#PART_Spinner"> <Style Selector="^ /template/ ButtonSpinner#PART_Spinner">
<Setter Property="MinHeight" Value="0"/> <Setter Property="MinHeight" Value="0"/>

View file

@ -41,7 +41,6 @@
<PackageReference Include="Avalonia" Version="11.1.3" /> <PackageReference Include="Avalonia" Version="11.1.3" />
<PackageReference Include="Avalonia.Desktop" Version="11.1.3" /> <PackageReference Include="Avalonia.Desktop" Version="11.1.3" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.3" /> <PackageReference Include="Avalonia.Themes.Fluent" Version="11.1.3" />
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.1.3" />
<PackageReference Include="Avalonia.Diagnostics" Version="11.1.3" Condition="'$(Configuration)' == 'Debug'" /> <PackageReference Include="Avalonia.Diagnostics" Version="11.1.3" Condition="'$(Configuration)' == 'Debug'" />
<PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" /> <PackageReference Include="Avalonia.AvaloniaEdit" Version="11.1.0" />
<PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" /> <PackageReference Include="AvaloniaEdit.TextMate" Version="11.1.0" />

View file

@ -180,16 +180,16 @@ namespace SourceGit.ViewModels
} }
} }
public ContextMenu MakeContextMenu(DataGrid datagrid) public ContextMenu MakeContextMenu(ListBox list)
{ {
if (datagrid.SelectedItems.Count != 1) if (list.SelectedItems.Count != 1)
return null; return null;
var current = _repo.CurrentBranch; var current = _repo.CurrentBranch;
if (current == null) if (current == null)
return null; return null;
var commit = (datagrid.SelectedItem as Models.Commit)!; var commit = (list.SelectedItem as Models.Commit)!;
var menu = new ContextMenu(); var menu = new ContextMenu();
var tags = new List<Models.Tag>(); var tags = new List<Models.Tag>();
@ -354,12 +354,11 @@ namespace SourceGit.ViewModels
return; return;
} }
var toplevel = datagrid.FindAncestorOfType<Views.Launcher>(); App.OpenDialog(new Views.InteractiveRebase()
if (toplevel == null) {
return; DataContext = new InteractiveRebase(_repo, current, commit)
});
var dialog = new Views.InteractiveRebase() { DataContext = new InteractiveRebase(_repo, current, commit) };
dialog.ShowDialog(toplevel);
e.Handled = true; e.Handled = true;
}; };
menu.Items.Add(interactiveRebase); menu.Items.Add(interactiveRebase);
@ -398,7 +397,7 @@ namespace SourceGit.ViewModels
} }
else else
{ {
datagrid.SelectedItems.Add(head); list.SelectedItems.Add(head);
} }
e.Handled = true; e.Handled = true;

View file

@ -8,162 +8,158 @@
xmlns:c="using:SourceGit.Converters" xmlns:c="using:SourceGit.Converters"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="SourceGit.Views.Histories" x:Class="SourceGit.Views.Histories"
x:DataType="vm:Histories"> x:DataType="vm:Histories"
x:Name="ThisControl">
<v:LayoutableGrid RowDefinitions="*,3,*" ColumnDefinitions="*,3,*" <v:LayoutableGrid RowDefinitions="*,3,*" ColumnDefinitions="*,3,*"
UseHorizontal="{Binding Source={x:Static vm:Preference.Instance}, Path=UseTwoColumnsLayoutInHistories}"> UseHorizontal="{Binding Source={x:Static vm:Preference.Instance}, Path=UseTwoColumnsLayoutInHistories}">
<Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"> <Grid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3">
<DataGrid x:Name="CommitDataGrid" <Grid RowDefinitions="24,*">
Background="{DynamicResource Brush.Contents}" <!-- Headers -->
ItemsSource="{Binding Commits}" <Border Grid.Row="0"
SelectionMode="Extended" Background="{DynamicResource Brush.Window}"
SelectedItem="{Binding AutoSelectedCommit, Mode=OneWay}" BorderThickness="0,0,0,1"
CanUserReorderColumns="False" BorderBrush="{DynamicResource Brush.Border0}">
CanUserResizeColumns="True" <Grid>
CanUserSortColumns="False" <Grid.ColumnDefinitions>
IsReadOnly="True" <ColumnDefinition Width="*" MinWidth="100"/>
HeadersVisibility="Column" <ColumnDefinition Width="1"/>
Focusable="False" <ColumnDefinition Width="{Binding #ThisControl.AuthorNameColumnWidth, Mode=TwoWay}" MinWidth="80"/>
RowHeight="28" <ColumnDefinition Width="96" MaxWidth="96" MinWidth="96"/>
ColumnHeaderHeight="24" <ColumnDefinition Width="156" MaxWidth="156" MinWidth="156"/>
HorizontalScrollBarVisibility="Disabled" </Grid.ColumnDefinitions>
VerticalScrollBarVisibility="Auto"
ClipboardCopyMode="None"
LayoutUpdated="OnCommitDataGridLayoutUpdated"
SelectionChanged="OnCommitDataGridSelectionChanged"
ContextRequested="OnCommitDataGridContextRequested"
DoubleTapped="OnCommitDataGridDoubleTapped"
KeyDown="OnCommitDataGridKeyDown">
<DataGrid.Styles>
<Style Selector="DataGridColumnHeader">
<Setter Property="MinHeight" Value="24"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Template">
<ControlTemplate>
<Border Background="{DynamicResource Brush.Window}"
BorderBrush="{DynamicResource Brush.Border0}"
BorderThickness="0,0,1,1">
<ContentPresenter x:Name="PART_ContentPresenter"
Content="{TemplateBinding Content}"
HorizontalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter>
</Style>
</DataGrid.Styles>
<DataGrid.Columns>
<DataGridTemplateColumn Width="*" CanUserResize="True">
<DataGridTemplateColumn.Header>
<TextBlock Classes="table_header" Text="{DynamicResource Text.Histories.Header.GraphAndSubject}"/>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate x:DataType="{x:Type m:Commit}">
<Border Margin="{Binding Margin}">
<StackPanel Orientation="Horizontal" Margin="2,0,0,0">
<v:CommitStatusIndicator CurrentBranch="{Binding $parent[v:Histories].CurrentBranch}"
AheadBrush="{DynamicResource Brush.Accent}"
BehindBrush="{DynamicResource Brush.FG1}"
VerticalAlignment="Center"/>
<v:CommitRefsPresenter IconBackground="{DynamicResource Brush.DecoratorIconBG}" <TextBlock Grid.Column="0" Classes="table_header" Text="{DynamicResource Text.Histories.Header.GraphAndSubject}" HorizontalAlignment="Center"/>
IconForeground="{DynamicResource Brush.DecoratorIcon}" <GridSplitter Grid.Column="1" Width="1" MinWidth="0.5" Background="{DynamicResource Brush.Border0}" HorizontalAlignment="Center" VerticalAlignment="Stretch"/>
BranchNameBackground="{DynamicResource Brush.DecoratorBranch}" <TextBlock Grid.Column="2" Classes="table_header" Text="{DynamicResource Text.Histories.Header.Author}" HorizontalAlignment="Center"/>
HeadBranchNameBackground="{DynamicResource Brush.DecoratorHead}" <Border Grid.Column="3" BorderThickness="1,0" BorderBrush="{DynamicResource Brush.Border0}" ClipToBounds="True">
TagNameBackground="{DynamicResource Brush.DecoratorTag}" <TextBlock Classes="table_header" Text="{DynamicResource Text.Histories.Header.SHA}" HorizontalAlignment="Center"/>
LabelForeground="{DynamicResource Brush.DecoratorFG}" </Border>
FontFamily="{DynamicResource Fonts.Primary}" <StackPanel Grid.Column="4" Orientation="Horizontal" HorizontalAlignment="Center">
FontSize="11" <ToggleButton Classes="time_display_mode"
VerticalAlignment="Center" Width="10" Height="10"
Refs="{Binding Decorators}"/> IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=DisplayTimeAsPeriodInHistories, Mode=TwoWay}"/>
<TextBlock Classes="table_header" Margin="6,0,0,0" Text="{DynamicResource Text.Histories.Header.Time}"/>
</StackPanel>
</Grid>
</Border>
<v:CommitSubjectPresenter Classes="primary" <!-- Commit Lists & Graph -->
Subject="{Binding Subject}" <Grid Grid.Row="1">
IssueTrackerRules="{Binding $parent[v:Histories].IssueTrackerRules}" <ListBox x:Name="CommitListContainer"
Opacity="{Binding Opacity}" Background="{DynamicResource Brush.Contents}"
FontWeight="{Binding FontWeight}"/> ItemsSource="{Binding Commits}"
</StackPanel> SelectionMode="Multiple"
</Border> SelectedItem="{Binding AutoSelectedCommit, Mode=OneWay}"
</DataTemplate> LayoutUpdated="OnCommitListLayoutUpdated"
</DataGridTemplateColumn.CellTemplate> SelectionChanged="OnCommitListSelectionChanged"
</DataGridTemplateColumn> ContextRequested="OnCommitListContextRequested"
DoubleTapped="OnCommitListDoubleTapped"
KeyDown="OnCommitListKeyDown">
<ListBox.Styles>
<Style Selector="ListBoxItem">
<Setter Property="Margin" Value="0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="Height" Value="28"/>
</Style>
</ListBox.Styles>
<DataGridTemplateColumn CanUserResize="True" Width="120"> <ListBox.ItemsPanel>
<DataGridTemplateColumn.Header> <ItemsPanelTemplate>
<TextBlock Classes="table_header" Text="{DynamicResource Text.Histories.Header.Author}"/> <VirtualizingStackPanel Orientation="Vertical"/>
</DataGridTemplateColumn.Header> </ItemsPanelTemplate>
</ListBox.ItemsPanel>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate x:DataType="{x:Type m:Commit}"> <ListBox.ItemTemplate>
<Grid ColumnDefinitions="Auto,*" Margin="8,0"> <DataTemplate DataType="m:Commit">
<v:Avatar Grid.Column="0" <Grid>
Width="16" Height="16" <Grid.ColumnDefinitions>
VerticalAlignment="Center" <ColumnDefinition Width="*"/>
IsHitTestVisible="False" <ColumnDefinition Width="{Binding #ThisControl.AuthorNameColumnWidth, Mode=OneWay}"/>
User="{Binding Author}" <ColumnDefinition Width="96" MaxWidth="96" MinWidth="96"/>
Opacity="{Binding Opacity}"/> <ColumnDefinition Width="156" MaxWidth="156" MinWidth="156"/>
<TextBlock Grid.Column="1" </Grid.ColumnDefinitions>
Classes="primary"
Text="{Binding Author.Name}" <!-- Subject & REFS -->
Margin="8,0,0,0" <Border Grid.Column="0" Padding="{Binding Margin}" ClipToBounds="True">
Opacity="{Binding Opacity}" <Grid ColumnDefinitions="Auto,Auto,*" Margin="2,0,4,0" ClipToBounds="True">
FontWeight="{Binding FontWeight}"/> <v:CommitStatusIndicator Grid.Column="0"
CurrentBranch="{Binding $parent[v:Histories].CurrentBranch}"
AheadBrush="{DynamicResource Brush.Accent}"
BehindBrush="{DynamicResource Brush.FG1}"
VerticalAlignment="Center"/>
<v:CommitRefsPresenter Grid.Column="1"
IconBackground="{DynamicResource Brush.DecoratorIconBG}"
IconForeground="{DynamicResource Brush.DecoratorIcon}"
BranchNameBackground="{DynamicResource Brush.DecoratorBranch}"
HeadBranchNameBackground="{DynamicResource Brush.DecoratorHead}"
TagNameBackground="{DynamicResource Brush.DecoratorTag}"
LabelForeground="{DynamicResource Brush.DecoratorFG}"
FontFamily="{DynamicResource Fonts.Primary}"
FontSize="11"
VerticalAlignment="Center"
Refs="{Binding Decorators}"/>
<v:CommitSubjectPresenter Grid.Column="2"
Classes="primary"
Subject="{Binding Subject}"
IssueTrackerRules="{Binding $parent[v:Histories].IssueTrackerRules}"
FontWeight="{Binding FontWeight}"
Opacity="{Binding Opacity}"/>
</Grid>
</Border>
<!-- Author -->
<Grid Grid.Column="1" ColumnDefinitions="16,*" Margin="8,0">
<v:Avatar Grid.Column="0"
Width="16" Height="16"
HorizontalAlignment="Center"
VerticalAlignment="Center"
IsHitTestVisible="False"
User="{Binding Author}"
Opacity="{Binding Opacity}"/>
<Border Grid.Column="1" Padding="8,0,0,0" ClipToBounds="True">
<TextBlock Classes="primary"
Text="{Binding Author.Name}"
FontWeight="{Binding FontWeight}"
HorizontalAlignment="Left"
Opacity="{Binding Opacity}"/>
</Border>
</Grid>
<!-- SHA -->
<Border Grid.Column="2" Padding="8,0" ClipToBounds="True">
<TextBlock Classes="primary"
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
HorizontalAlignment="Center"
FontWeight="{Binding FontWeight}"
Opacity="{Binding Opacity}"/>
</Border>
<!-- COMMIT TIME -->
<Border Grid.Column="3" Padding="8,0" ClipToBounds="True">
<v:CommitTimeTextBlock Classes="primary"
HorizontalAlignment="Center"
FontWeight="{Binding FontWeight}"
Opacity="{Binding Opacity}"
Timestamp="{Binding CommitterTime}"
ShowAsDateTime="{Binding Source={x:Static vm:Preference.Instance}, Path=!DisplayTimeAsPeriodInHistories}"/>
</Border>
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</DataGridTemplateColumn.CellTemplate> </ListBox.ItemTemplate>
</DataGridTemplateColumn> </ListBox>
<DataGridTemplateColumn CanUserResize="False" MinWidth="96">
<DataGridTemplateColumn.Header>
<TextBlock Classes="table_header" Text="{DynamicResource Text.Histories.Header.SHA}"/>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate x:DataType="{x:Type m:Commit}">
<TextBlock Classes="primary"
Text="{Binding SHA, Converter={x:Static c:StringConverters.ToShortSHA}}"
Margin="8,0"
HorizontalAlignment="Center"
Opacity="{Binding Opacity}"
FontWeight="{Binding FontWeight}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn CanUserResize="False" MinWidth="156">
<DataGridTemplateColumn.Header>
<StackPanel Orientation="Horizontal">
<ToggleButton Classes="time_display_mode"
Width="10" Height="10"
IsChecked="{Binding Source={x:Static vm:Preference.Instance}, Path=DisplayTimeAsPeriodInHistories, Mode=TwoWay}"/>
<TextBlock Classes="table_header" Margin="6,0,0,0" Text="{DynamicResource Text.Histories.Header.Time}"/>
</StackPanel>
</DataGridTemplateColumn.Header>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate x:DataType="{x:Type m:Commit}">
<v:CommitTimeTextBlock Classes="primary"
Margin="8,0"
HorizontalAlignment="Center"
Opacity="{Binding Opacity}"
FontWeight="{Binding FontWeight}"
Timestamp="{Binding CommitterTime}"
ShowAsDateTime="{Binding Source={x:Static vm:Preference.Instance}, Path=!DisplayTimeAsPeriodInHistories}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<v:CommitGraph x:Name="CommitGraph"
Graph="{Binding Graph}"
DotBrush="{DynamicResource Brush.Contents}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
IsHitTestVisible="False"
ClipToBounds="True"/>
<v:CommitGraph x:Name="CommitGraph"
Graph="{Binding Graph}"
DotBrush="{DynamicResource Brush.Contents}"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
IsHitTestVisible="False"
ClipToBounds="True"/>
</Grid>
</Grid>
<!-- Fix memory leak --> <!-- Fix memory leak -->
<v:LoadingIcon Width="48" Height="48" HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{Binding IsLoading}"/> <v:LoadingIcon Width="48" Height="48" HorizontalAlignment="Center" VerticalAlignment="Center" IsVisible="{Binding IsLoading}"/>
</Grid> </Grid>

View file

@ -439,41 +439,29 @@ namespace SourceGit.Views
{ {
base.Render(context); base.Render(context);
var grid = this.FindAncestorOfType<Histories>()?.CommitDataGrid; var histories = this.FindAncestorOfType<Histories>();
if (grid == null) if (histories == null)
return;
var list = histories.CommitListContainer;
if (list == null)
return; return;
var graph = Graph; var graph = Graph;
if (graph == null) if (graph == null)
return; return;
var rowsPresenter = grid.FindDescendantOfType<DataGridRowsPresenter>(); double rowHeight = 28;
if (rowsPresenter == null) double startY = list.Scroll?.Offset.Y ?? 0;
return; double maxWidth = Bounds.Width - 156 - 96 - histories.AuthorNameColumnWidth.Value;
// Find the content display offset Y of binding DataGrid.
double rowHeight = grid.RowHeight;
double startY = 0;
foreach (var child in rowsPresenter.Children)
{
if (child is DataGridRow { IsVisible: true, Bounds.Top: <= 0 } row && row.Bounds.Top > -rowHeight)
{
var test = rowHeight * row.GetIndex() - row.Bounds.Top;
if (startY < test)
startY = test;
}
}
var headerHeight = grid.ColumnHeaderHeight;
startY -= headerHeight;
// Apply scroll offset. // Apply scroll offset.
context.PushClip(new Rect(Bounds.Left, Bounds.Top + headerHeight, grid.Columns[0].ActualWidth, Bounds.Height)); context.PushClip(new Rect(Bounds.Left, Bounds.Top, maxWidth, Bounds.Height));
context.PushTransform(Matrix.CreateTranslation(0, -startY)); context.PushTransform(Matrix.CreateTranslation(0, -startY));
// Calculate bounds. // Calculate bounds.
var top = startY; var top = startY;
var bottom = startY + grid.Bounds.Height + rowHeight * 2; var bottom = startY + Bounds.Height + rowHeight * 2;
// Draw contents // Draw contents
DrawCurves(context, graph, top, bottom); DrawCurves(context, graph, top, bottom);
@ -602,6 +590,15 @@ namespace SourceGit.Views
public partial class Histories : UserControl public partial class Histories : UserControl
{ {
public static readonly StyledProperty<GridLength> AuthorNameColumnWidthProperty =
AvaloniaProperty.Register<Histories, GridLength>(nameof(AuthorNameColumnWidth), new GridLength(120));
public GridLength AuthorNameColumnWidth
{
get => GetValue(AuthorNameColumnWidthProperty);
set => SetValue(AuthorNameColumnWidthProperty, value);
}
public static readonly StyledProperty<Models.Branch> CurrentBranchProperty = public static readonly StyledProperty<Models.Branch> CurrentBranchProperty =
AvaloniaProperty.Register<Histories, Models.Branch>(nameof(CurrentBranch)); AvaloniaProperty.Register<Histories, Models.Branch>(nameof(CurrentBranch));
@ -637,9 +634,9 @@ namespace SourceGit.Views
return; return;
// Force scroll selected item (current head) into view. see issue #58 // Force scroll selected item (current head) into view. see issue #58
var datagrid = h.CommitDataGrid; var list = h.CommitListContainer;
if (datagrid != null && datagrid.SelectedItems.Count == 1) if (list != null && list.SelectedItems.Count == 1)
datagrid.ScrollIntoView(datagrid.SelectedItems[0], null); list.ScrollIntoView(list.SelectedIndex);
}); });
} }
@ -648,43 +645,42 @@ namespace SourceGit.Views
InitializeComponent(); InitializeComponent();
} }
private void OnCommitDataGridLayoutUpdated(object _1, EventArgs _2) private void OnCommitListLayoutUpdated(object _1, EventArgs _2)
{ {
CommitGraph.InvalidateVisual(); CommitGraph.InvalidateVisual();
} }
private void OnCommitDataGridSelectionChanged(object _, SelectionChangedEventArgs e) private void OnCommitListSelectionChanged(object _, SelectionChangedEventArgs e)
{ {
if (DataContext is ViewModels.Histories histories) if (DataContext is ViewModels.Histories histories)
{ {
histories.Select(CommitDataGrid.SelectedItems); histories.Select(CommitListContainer.SelectedItems);
} }
e.Handled = true; e.Handled = true;
} }
private void OnCommitDataGridContextRequested(object sender, ContextRequestedEventArgs e) private void OnCommitListContextRequested(object sender, ContextRequestedEventArgs e)
{ {
if (DataContext is ViewModels.Histories histories && sender is DataGrid datagrid) if (DataContext is ViewModels.Histories histories && sender is ListBox list)
{ {
var menu = histories.MakeContextMenu(datagrid); var menu = histories.MakeContextMenu(list);
datagrid.OpenContextMenu(menu); list.OpenContextMenu(menu);
} }
e.Handled = true; e.Handled = true;
} }
private void OnCommitDataGridDoubleTapped(object sender, TappedEventArgs e) private void OnCommitListDoubleTapped(object sender, TappedEventArgs e)
{ {
if (DataContext is ViewModels.Histories histories && sender is DataGrid datagrid && datagrid.SelectedItems is { Count: 1 } selectedItems) if (DataContext is ViewModels.Histories histories && sender is ListBox { SelectedItems: { Count: 1 } selected })
{ {
histories.DoubleTapped(selectedItems[0] as Models.Commit); histories.DoubleTapped(selected[0] as Models.Commit);
} }
e.Handled = true; e.Handled = true;
} }
private void OnCommitDataGridKeyDown(object sender, KeyEventArgs e) private void OnCommitListKeyDown(object sender, KeyEventArgs e)
{ {
if (sender is DataGrid grid && if (sender is ListBox { SelectedItems: { Count : 1 } selected } &&
grid.SelectedItems is { Count: > 0 } selected &&
e.Key == Key.C && e.Key == Key.C &&
e.KeyModifiers.HasFlag(KeyModifiers.Control)) e.KeyModifiers.HasFlag(KeyModifiers.Control))
{ {