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