Fix null file bug and add context menu to my ratings column
This commit is contained in:
parent
613cfdd903
commit
a7bf30954d
@ -1,5 +0,0 @@
|
||||
<DataGridCheckBoxColumn xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
x:Class="LibationAvalonia.Controls.DataGridCheckBoxColumnExt">
|
||||
|
||||
</DataGridCheckBoxColumn >
|
||||
@ -1,10 +1,11 @@
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Controls;
|
||||
using LibationAvalonia.ViewModels;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace LibationAvalonia.Controls
|
||||
{
|
||||
public partial class DataGridCheckBoxColumnExt : DataGridCheckBoxColumn
|
||||
public class DataGridCheckBoxColumnExt : DataGridCheckBoxColumn
|
||||
{
|
||||
protected override IControl GenerateEditingElementDirect(DataGridCell cell, object dataItem)
|
||||
{
|
||||
@ -1,6 +1,5 @@
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Collections;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using LibationAvalonia.ViewModels;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
@ -19,36 +18,46 @@ namespace LibationAvalonia.Controls
|
||||
=> GetCellValueMethod.Invoke(column, new object[] { item, column.ClipboardContentBinding })?.ToString() ?? "";
|
||||
|
||||
public string CellClipboardContents => GetCellValue(Column, GridEntry);
|
||||
public DataGridTemplateColumnExt Column { get; init; }
|
||||
public DataGridColumn Column { get; init; }
|
||||
public GridEntry GridEntry { get; init; }
|
||||
public ContextMenu ContextMenu { get; init; }
|
||||
public AvaloniaList<MenuItem> ContextMenuItems
|
||||
=> ContextMenu.Items as AvaloniaList<MenuItem>;
|
||||
}
|
||||
|
||||
public partial class DataGridTemplateColumnExt : DataGridTemplateColumn
|
||||
internal static class DataGridContextMenus
|
||||
{
|
||||
public event EventHandler<DataGridCellContextMenuStripNeededEventArgs> CellContextMenuStripNeeded;
|
||||
|
||||
public static event EventHandler<DataGridCellContextMenuStripNeededEventArgs> CellContextMenuStripNeeded;
|
||||
private static readonly ContextMenu ContextMenu = new();
|
||||
private static readonly AvaloniaList<MenuItem> MenuItems = new();
|
||||
private static readonly PropertyInfo OwningColumnProperty;
|
||||
|
||||
public DataGridTemplateColumnExt()
|
||||
static DataGridContextMenus()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
ContextMenu.Items = MenuItems;
|
||||
OwningColumnProperty = typeof(DataGridCell).GetProperty("OwningColumn", BindingFlags.Instance | BindingFlags.NonPublic);
|
||||
}
|
||||
|
||||
private void Cell_ContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
public static void AttachContextMenuToCell(this DataGridCell cell)
|
||||
{
|
||||
if (cell.ContextMenu is null)
|
||||
{
|
||||
cell.ContextRequested += Cell_ContextRequested;
|
||||
cell.ContextMenu = ContextMenu;
|
||||
}
|
||||
}
|
||||
|
||||
private static void Cell_ContextRequested(object sender, ContextRequestedEventArgs e)
|
||||
{
|
||||
if (sender is DataGridCell cell && cell.DataContext is GridEntry entry)
|
||||
{
|
||||
var args = new DataGridCellContextMenuStripNeededEventArgs
|
||||
{
|
||||
Column = this,
|
||||
Column = OwningColumnProperty.GetValue(cell) as DataGridColumn,
|
||||
GridEntry = entry,
|
||||
ContextMenu = ContextMenu
|
||||
};
|
||||
|
||||
args.ContextMenuItems.Clear();
|
||||
|
||||
CellContextMenuStripNeeded?.Invoke(sender, args);
|
||||
@ -58,16 +67,5 @@ namespace LibationAvalonia.Controls
|
||||
else
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
protected override IControl GenerateElement(DataGridCell cell, object dataItem)
|
||||
{
|
||||
if (cell.ContextMenu is null)
|
||||
{
|
||||
cell.ContextRequested += Cell_ContextRequested;
|
||||
cell.ContextMenu = ContextMenu;
|
||||
}
|
||||
|
||||
return base.GenerateElement(cell, dataItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,17 +1,15 @@
|
||||
using Avalonia;
|
||||
using Avalonia;
|
||||
using Avalonia.Controls;
|
||||
using Avalonia.Interactivity;
|
||||
using Avalonia.Markup.Xaml;
|
||||
using DataLayer;
|
||||
|
||||
namespace LibationAvalonia.Controls
|
||||
{
|
||||
public partial class MyRatingGridColumn : DataGridBoundColumn
|
||||
public class DataGridMyRatingColumn : DataGridBoundColumn
|
||||
{
|
||||
private static Rating DefaultRating => new Rating(0, 0, 0);
|
||||
public MyRatingGridColumn()
|
||||
public DataGridMyRatingColumn()
|
||||
{
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
BindingTarget = MyRatingCellEditor.RatingProperty;
|
||||
}
|
||||
|
||||
@ -20,40 +18,26 @@ namespace LibationAvalonia.Controls
|
||||
var myRatingElement = new MyRatingCellEditor
|
||||
{
|
||||
Name = "CellMyRatingDisplay",
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center,
|
||||
IsEditingMode = false,
|
||||
Margin = new Thickness(3),
|
||||
IsEnabled = false
|
||||
IsEditingMode = false
|
||||
};
|
||||
|
||||
//Create a panel that fills the cell to host the rating tool tip
|
||||
var panel = new Panel
|
||||
{
|
||||
Background = Avalonia.Media.Brushes.Transparent,
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Stretch,
|
||||
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Stretch,
|
||||
};
|
||||
panel.Children.Add(myRatingElement);
|
||||
|
||||
ToolTip.SetTip(panel, "Click to change ratings");
|
||||
ToolTip.SetTip(myRatingElement, "Click to change ratings");
|
||||
cell?.AttachContextMenuToCell();
|
||||
|
||||
if (Binding != null)
|
||||
{
|
||||
myRatingElement.Bind(BindingTarget, Binding);
|
||||
}
|
||||
return panel;
|
||||
|
||||
return myRatingElement;
|
||||
}
|
||||
|
||||
protected override IControl GenerateEditingElementDirect(DataGridCell cell, object dataItem)
|
||||
{
|
||||
var myRatingElement = new MyRatingCellEditor
|
||||
{
|
||||
Name = "CellMyRatingCellEditor",
|
||||
HorizontalAlignment = Avalonia.Layout.HorizontalAlignment.Left,
|
||||
VerticalAlignment = Avalonia.Layout.VerticalAlignment.Center,
|
||||
IsEditingMode = true,
|
||||
Margin = new Thickness(3)
|
||||
Name = "CellMyRatingEditor",
|
||||
IsEditingMode = true
|
||||
};
|
||||
|
||||
return myRatingElement;
|
||||
@ -1,7 +0,0 @@
|
||||
<DataGridTemplateColumn xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Class="LibationAvalonia.Controls.DataGridTemplateColumnExt">
|
||||
|
||||
</DataGridTemplateColumn>
|
||||
@ -0,0 +1,15 @@
|
||||
using Avalonia.Controls;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace LibationAvalonia.Controls
|
||||
{
|
||||
public partial class DataGridTemplateColumnExt : DataGridTemplateColumn
|
||||
{
|
||||
protected override IControl GenerateElement(DataGridCell cell, object dataItem)
|
||||
{
|
||||
cell?.AttachContextMenuToCell();
|
||||
return base.GenerateElement(cell, dataItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,10 +2,11 @@
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
mc:Ignorable="d" d:DesignWidth="115" d:DesignHeight="80"
|
||||
x:Class="LibationAvalonia.Controls.MyRatingCellEditor">
|
||||
|
||||
<Grid ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto">
|
||||
<Panel Background="Transparent" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
|
||||
<Grid Name="ratingsGrid" HorizontalAlignment="Left" VerticalAlignment="Center" Margin="3,0,0,0" ColumnDefinitions="Auto,*" RowDefinitions="Auto,Auto,Auto">
|
||||
<Grid.Styles>
|
||||
<Style Selector="TextBlock">
|
||||
<Setter Property="FontSize" Value="11" />
|
||||
@ -49,4 +50,5 @@
|
||||
</StackPanel>
|
||||
</Panel>
|
||||
</Grid>
|
||||
</Panel>
|
||||
</UserControl>
|
||||
|
||||
@ -14,11 +14,8 @@ namespace LibationAvalonia.Controls
|
||||
AvaloniaProperty.Register<MyRatingCellEditor, Rating>(nameof(Rating));
|
||||
|
||||
public bool IsEditingMode { get; set; }
|
||||
public Rating Rating
|
||||
{
|
||||
get { return GetValue(RatingProperty); }
|
||||
set { SetValue(RatingProperty, value); }
|
||||
}
|
||||
public Rating Rating { get => GetValue(RatingProperty); set => SetValue(RatingProperty, value); }
|
||||
|
||||
public MyRatingCellEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
@ -44,16 +41,17 @@ namespace LibationAvalonia.Controls
|
||||
foreach (TextBlock star in panelStory.Children)
|
||||
star.Tag = star.Text = Rating.StoryRating > rating++ ? SOLID_STAR : blankValue;
|
||||
|
||||
SetVisible(IsEditingMode);
|
||||
SetVisible();
|
||||
}
|
||||
base.OnPropertyChanged(change);
|
||||
}
|
||||
|
||||
private void SetVisible(bool allVisible)
|
||||
private void SetVisible()
|
||||
{
|
||||
tblockOverall.IsVisible = panelOverall.IsVisible = allVisible || Rating?.OverallRating > 0;
|
||||
tblockPerform.IsVisible = panelPerform.IsVisible = allVisible || Rating?.PerformanceRating > 0;
|
||||
tblockStory.IsVisible = panelStory.IsVisible = allVisible || Rating?.StoryRating > 0;
|
||||
ratingsGrid.IsEnabled = IsEditingMode;
|
||||
tblockOverall.IsVisible = panelOverall.IsVisible = IsEditingMode || Rating?.OverallRating > 0;
|
||||
tblockPerform.IsVisible = panelPerform.IsVisible = IsEditingMode || Rating?.PerformanceRating > 0;
|
||||
tblockStory.IsVisible = panelStory.IsVisible = IsEditingMode || Rating?.StoryRating > 0;
|
||||
}
|
||||
|
||||
public void Panel_PointerExited(object sender, Avalonia.Input.PointerEventArgs e)
|
||||
|
||||
@ -1,8 +0,0 @@
|
||||
<DataGridBoundColumn xmlns="https://github.com/avaloniaui"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
|
||||
x:Class="LibationAvalonia.Controls.MyRatingGridColumn">
|
||||
|
||||
</DataGridBoundColumn>
|
||||
@ -131,7 +131,7 @@ namespace LibationAvalonia.Dialogs
|
||||
var selectedFiles = await StorageProvider.OpenFilePickerAsync(openFileDialogOptions);
|
||||
var selectedFile = selectedFiles.SingleOrDefault();
|
||||
|
||||
if (!selectedFile.TryGetUri(out var uri)) return;
|
||||
if (selectedFile?.TryGetUri(out var uri) is not true) return;
|
||||
|
||||
try
|
||||
{
|
||||
@ -291,7 +291,7 @@ namespace LibationAvalonia.Dialogs
|
||||
|
||||
var selectedFile = await StorageProvider.SaveFilePickerAsync(options);
|
||||
|
||||
if (!selectedFile.TryGetUri(out var uri)) return;
|
||||
if (selectedFile?.TryGetUri(out var uri) is not true) return;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@ -51,7 +51,7 @@ namespace LibationAvalonia.Dialogs
|
||||
{
|
||||
Title = $"Save Sover Image",
|
||||
SuggestedStartLocation = new Avalonia.Platform.Storage.FileIO.BclStorageFolder(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures)),
|
||||
SuggestedFileName = $"{PictureFileName}.jpg",
|
||||
SuggestedFileName = PictureFileName,
|
||||
DefaultExtension = "jpg",
|
||||
ShowOverwritePrompt = true,
|
||||
FileTypeChoices = new FilePickerFileType[]
|
||||
@ -62,7 +62,7 @@ namespace LibationAvalonia.Dialogs
|
||||
|
||||
var selectedFile = await StorageProvider.SaveFilePickerAsync(options);
|
||||
|
||||
if (!selectedFile.TryGetUri(out var uri)) return;
|
||||
if (selectedFile?.TryGetUri(out var uri) is not true) return;
|
||||
|
||||
try
|
||||
{
|
||||
|
||||
@ -34,7 +34,7 @@ namespace LibationAvalonia.Views
|
||||
|
||||
var selectedFile = await StorageProvider.SaveFilePickerAsync(options);
|
||||
|
||||
if (!selectedFile.TryGetUri(out var uri)) return;
|
||||
if (selectedFile?.TryGetUri(out var uri) is not true) return;
|
||||
|
||||
var ext = System.IO.Path.GetExtension(uri.LocalPath);
|
||||
switch (ext)
|
||||
|
||||
@ -160,8 +160,7 @@
|
||||
</DataGridTemplateColumn.CellTemplate>
|
||||
</controls:DataGridTemplateColumnExt>
|
||||
|
||||
|
||||
<controls:MyRatingGridColumn IsReadOnly="false" Width="115" Header="My Rating" CanUserSort="True" SortMemberPath="MyRating" ClipboardContentBinding="{Binding MyRatingString}" Binding="{Binding MyRating, Mode=TwoWay}" />
|
||||
<controls:DataGridMyRatingColumn IsReadOnly="false" Width="115" Header="My Rating" CanUserSort="True" SortMemberPath="MyRating" ClipboardContentBinding="{Binding MyRatingString}" Binding="{Binding MyRating, Mode=TwoWay}" />
|
||||
|
||||
<controls:DataGridTemplateColumnExt Width="135" Header="Misc" CanUserSort="True" SortMemberPath="Misc" ClipboardContentBinding="{Binding Misc}">
|
||||
<DataGridTemplateColumn.CellTemplate>
|
||||
|
||||
@ -71,6 +71,7 @@ namespace LibationAvalonia.Views
|
||||
AvaloniaXamlLoader.Load(this);
|
||||
|
||||
productsGrid = this.FindControl<DataGrid>(nameof(productsGrid));
|
||||
DataGridContextMenus.CellContextMenuStripNeeded += ProductsGrid_CellContextMenuStripNeeded;
|
||||
}
|
||||
|
||||
#region Cell Context Menu
|
||||
@ -121,7 +122,7 @@ namespace LibationAvalonia.Views
|
||||
var selectedFiles = await this.GetParentWindow().StorageProvider.OpenFilePickerAsync(openFileDialogOptions);
|
||||
var selectedFile = selectedFiles.SingleOrDefault();
|
||||
|
||||
if (selectedFile.TryGetUri(out var uri))
|
||||
if (selectedFile?.TryGetUri(out var uri) is true)
|
||||
FilePathCache.Insert(entry.AudibleProductId, uri.LocalPath);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -179,10 +180,6 @@ namespace LibationAvalonia.Views
|
||||
|
||||
foreach (var column in productsGrid.Columns)
|
||||
{
|
||||
//Wire up column context menu
|
||||
if (column is DataGridTemplateColumnExt tc)
|
||||
tc.CellContextMenuStripNeeded += ProductsGrid_CellContextMenuStripNeeded;
|
||||
|
||||
var itemName = column.SortMemberPath;
|
||||
|
||||
if (itemName == nameof(GridEntry.Remove))
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user