Пагинация запросов и исправление отображений
This commit is contained in:
@@ -4,7 +4,9 @@ using Newtonsoft.Json.Linq;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
using Pf2eModel.Model.Base.Source;
|
||||
using Pf2eModel.Model.Structure;
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Pf2eViewer;
|
||||
internal class EntityConverter : JsonConverter
|
||||
@@ -16,44 +18,62 @@ internal class EntityConverter : JsonConverter
|
||||
return objectType == typeof(Entity) || objectType.IsAssignableTo(typeof(IEntity));
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||
private Dictionary<string, object?> DictionarySerialization(object source)
|
||||
{
|
||||
JToken token = JToken.FromObject(value!);
|
||||
Dictionary<string, object?> dictionary = [];
|
||||
|
||||
if (token.Type != JTokenType.Object)
|
||||
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(source))
|
||||
{
|
||||
token.WriteTo(writer);
|
||||
return;
|
||||
object? v = property.GetValue(source);
|
||||
dictionary.Add(property.Name, v);
|
||||
}
|
||||
|
||||
JObject obj = (JObject) token;
|
||||
return dictionary;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
|
||||
{
|
||||
Dictionary<string, object?> dictionary = DictionarySerialization(value!);
|
||||
|
||||
if (value.GetType() != typeof(Entity))
|
||||
{
|
||||
dictionary.Remove("Entity");
|
||||
}
|
||||
|
||||
switch (value)
|
||||
{
|
||||
case Entity e:
|
||||
obj = ProcessEntity(obj, e);
|
||||
case Entity entity:
|
||||
ProcessEntity(dictionary, entity);
|
||||
break;
|
||||
|
||||
case Trait trait:
|
||||
ProcessTrait(dictionary, trait);
|
||||
break;
|
||||
}
|
||||
|
||||
obj.WriteTo(writer);
|
||||
writer.WriteStartObject();
|
||||
|
||||
foreach (KeyValuePair<string, object> keyValuePair in dictionary)
|
||||
{
|
||||
writer.WritePropertyName(keyValuePair.Key, true);
|
||||
serializer.Serialize(writer, keyValuePair.Value);
|
||||
}
|
||||
|
||||
private JObject ProcessEntity(JObject obj, Entity e)
|
||||
{
|
||||
List<int> traitIds = e.Traits.Select(t => t.Id).ToList();
|
||||
List<Trait> traits = _context.Traits.Where(t => traitIds.Contains(t.Id)).Include(t => t.Entity).ToList();
|
||||
|
||||
foreach (JToken item in (JArray) obj.SelectToken("Traits")!)
|
||||
{
|
||||
JObject o = (JObject) item;
|
||||
int id = o.SelectToken("Id")!.ToObject<int>();
|
||||
|
||||
o.Add("Name", traits.FirstOrDefault(t => t.Id == id)!.Entity.Name);
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
|
||||
obj.Remove("Description");
|
||||
private void ProcessTrait(Dictionary<string, object?> dictionary, Trait trait)
|
||||
{
|
||||
string name = trait.Entity?.Name ?? _context.Entities.Where(e => e.Id == trait.Id).Select(e => e.Name).FirstOrDefault()!;
|
||||
|
||||
return obj;
|
||||
dictionary.Remove("Entity");
|
||||
dictionary.Remove("Entities");
|
||||
dictionary.Add("Name", name);
|
||||
}
|
||||
|
||||
private void ProcessEntity(Dictionary<string, object?> dictionary, Entity entity)
|
||||
{
|
||||
dictionary.Remove("Description");
|
||||
}
|
||||
|
||||
public override bool CanRead => false;
|
||||
|
||||
Generated
+107
-10
@@ -32,6 +32,13 @@ partial class MainViewForm
|
||||
InnerSplitContainer = new SplitContainer();
|
||||
TypesListBox = new ListBox();
|
||||
EntityGridView = new DataGridView();
|
||||
PaginationPagel = new Panel();
|
||||
PageTextBox = new TextBox();
|
||||
PaginationLabel = new TextBox();
|
||||
LastPageButton = new Button();
|
||||
NextPageButton = new Button();
|
||||
PrevPageButton = new Button();
|
||||
FirstPageButton = new Button();
|
||||
ResultSplitContainer = new SplitContainer();
|
||||
EntityTreeView = new TreeView();
|
||||
DescriptionTextBox = new TextBox();
|
||||
@@ -44,6 +51,7 @@ partial class MainViewForm
|
||||
InnerSplitContainer.Panel2.SuspendLayout();
|
||||
InnerSplitContainer.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize) EntityGridView).BeginInit();
|
||||
PaginationPagel.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize) ResultSplitContainer).BeginInit();
|
||||
ResultSplitContainer.Panel1.SuspendLayout();
|
||||
ResultSplitContainer.Panel2.SuspendLayout();
|
||||
@@ -66,7 +74,7 @@ partial class MainViewForm
|
||||
RootSplitContainer.Panel2.Controls.Add(ResultSplitContainer);
|
||||
RootSplitContainer.Panel2MinSize = 400;
|
||||
RootSplitContainer.Size = new Size(1181, 688);
|
||||
RootSplitContainer.SplitterDistance = 200;
|
||||
RootSplitContainer.SplitterDistance = 254;
|
||||
RootSplitContainer.TabIndex = 0;
|
||||
//
|
||||
// InnerSplitContainer
|
||||
@@ -83,8 +91,9 @@ partial class MainViewForm
|
||||
// InnerSplitContainer.Panel2
|
||||
//
|
||||
InnerSplitContainer.Panel2.Controls.Add(EntityGridView);
|
||||
InnerSplitContainer.Size = new Size(200, 688);
|
||||
InnerSplitContainer.SplitterDistance = 274;
|
||||
InnerSplitContainer.Panel2.Controls.Add(PaginationPagel);
|
||||
InnerSplitContainer.Size = new Size(254, 688);
|
||||
InnerSplitContainer.SplitterDistance = 102;
|
||||
InnerSplitContainer.TabIndex = 1;
|
||||
//
|
||||
// TypesListBox
|
||||
@@ -94,7 +103,7 @@ partial class MainViewForm
|
||||
TypesListBox.ItemHeight = 15;
|
||||
TypesListBox.Location = new Point(0, 0);
|
||||
TypesListBox.Name = "TypesListBox";
|
||||
TypesListBox.Size = new Size(200, 274);
|
||||
TypesListBox.Size = new Size(254, 102);
|
||||
TypesListBox.TabIndex = 0;
|
||||
TypesListBox.SelectedIndexChanged += TypesListBox_SelectedIndexChanged;
|
||||
//
|
||||
@@ -105,17 +114,96 @@ partial class MainViewForm
|
||||
EntityGridView.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
|
||||
EntityGridView.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||
EntityGridView.Dock = DockStyle.Fill;
|
||||
EntityGridView.Location = new Point(0, 0);
|
||||
EntityGridView.Location = new Point(0, 53);
|
||||
EntityGridView.MultiSelect = false;
|
||||
EntityGridView.Name = "EntityGridView";
|
||||
EntityGridView.ReadOnly = true;
|
||||
EntityGridView.RowHeadersVisible = false;
|
||||
EntityGridView.RowHeadersWidthSizeMode = DataGridViewRowHeadersWidthSizeMode.AutoSizeToDisplayedHeaders;
|
||||
EntityGridView.ShowEditingIcon = false;
|
||||
EntityGridView.Size = new Size(200, 410);
|
||||
EntityGridView.Size = new Size(254, 529);
|
||||
EntityGridView.TabIndex = 0;
|
||||
EntityGridView.RowStateChanged += EntityGridView_RowStateChanged;
|
||||
//
|
||||
// PaginationPagel
|
||||
//
|
||||
PaginationPagel.Controls.Add(PageTextBox);
|
||||
PaginationPagel.Controls.Add(PaginationLabel);
|
||||
PaginationPagel.Controls.Add(LastPageButton);
|
||||
PaginationPagel.Controls.Add(NextPageButton);
|
||||
PaginationPagel.Controls.Add(PrevPageButton);
|
||||
PaginationPagel.Controls.Add(FirstPageButton);
|
||||
PaginationPagel.Dock = DockStyle.Top;
|
||||
PaginationPagel.Location = new Point(0, 0);
|
||||
PaginationPagel.Name = "PaginationPagel";
|
||||
PaginationPagel.Size = new Size(254, 53);
|
||||
PaginationPagel.TabIndex = 1;
|
||||
//
|
||||
// PageTextBox
|
||||
//
|
||||
PageTextBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||
PageTextBox.Location = new Point(81, 4);
|
||||
PageTextBox.Name = "PageTextBox";
|
||||
PageTextBox.Size = new Size(92, 23);
|
||||
PageTextBox.TabIndex = 8;
|
||||
PageTextBox.Text = "1";
|
||||
PageTextBox.TextAlign = HorizontalAlignment.Center;
|
||||
PageTextBox.KeyPress += PageTextBox_KeyPress;
|
||||
//
|
||||
// PaginationLabel
|
||||
//
|
||||
PaginationLabel.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
|
||||
PaginationLabel.BorderStyle = BorderStyle.None;
|
||||
PaginationLabel.Location = new Point(3, 31);
|
||||
PaginationLabel.Name = "PaginationLabel";
|
||||
PaginationLabel.ReadOnly = true;
|
||||
PaginationLabel.Size = new Size(248, 16);
|
||||
PaginationLabel.TabIndex = 7;
|
||||
PaginationLabel.Text = "Всего";
|
||||
PaginationLabel.TextAlign = HorizontalAlignment.Center;
|
||||
//
|
||||
// LastPageButton
|
||||
//
|
||||
LastPageButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||
LastPageButton.Location = new Point(218, 3);
|
||||
LastPageButton.Name = "LastPageButton";
|
||||
LastPageButton.Size = new Size(33, 23);
|
||||
LastPageButton.TabIndex = 3;
|
||||
LastPageButton.Text = ">>";
|
||||
LastPageButton.UseVisualStyleBackColor = true;
|
||||
LastPageButton.Click += LastPageButton_Click;
|
||||
//
|
||||
// NextPageButton
|
||||
//
|
||||
NextPageButton.Anchor = AnchorStyles.Top | AnchorStyles.Right;
|
||||
NextPageButton.Location = new Point(179, 3);
|
||||
NextPageButton.Name = "NextPageButton";
|
||||
NextPageButton.Size = new Size(33, 23);
|
||||
NextPageButton.TabIndex = 2;
|
||||
NextPageButton.Text = ">";
|
||||
NextPageButton.UseVisualStyleBackColor = true;
|
||||
NextPageButton.Click += NextPageButton_Click;
|
||||
//
|
||||
// PrevPageButton
|
||||
//
|
||||
PrevPageButton.Location = new Point(42, 3);
|
||||
PrevPageButton.Name = "PrevPageButton";
|
||||
PrevPageButton.Size = new Size(33, 23);
|
||||
PrevPageButton.TabIndex = 1;
|
||||
PrevPageButton.Text = "<";
|
||||
PrevPageButton.UseVisualStyleBackColor = true;
|
||||
PrevPageButton.Click += PrevPageButton_Click;
|
||||
//
|
||||
// FirstPageButton
|
||||
//
|
||||
FirstPageButton.Location = new Point(3, 3);
|
||||
FirstPageButton.Name = "FirstPageButton";
|
||||
FirstPageButton.Size = new Size(33, 23);
|
||||
FirstPageButton.TabIndex = 0;
|
||||
FirstPageButton.Text = "<<";
|
||||
FirstPageButton.UseVisualStyleBackColor = true;
|
||||
FirstPageButton.Click += FirstPageButton_Click;
|
||||
//
|
||||
// ResultSplitContainer
|
||||
//
|
||||
ResultSplitContainer.Dock = DockStyle.Fill;
|
||||
@@ -129,8 +217,8 @@ partial class MainViewForm
|
||||
// ResultSplitContainer.Panel2
|
||||
//
|
||||
ResultSplitContainer.Panel2.Controls.Add(DescriptionTextBox);
|
||||
ResultSplitContainer.Size = new Size(977, 688);
|
||||
ResultSplitContainer.SplitterDistance = 495;
|
||||
ResultSplitContainer.Size = new Size(923, 688);
|
||||
ResultSplitContainer.SplitterDistance = 467;
|
||||
ResultSplitContainer.TabIndex = 1;
|
||||
//
|
||||
// EntityTreeView
|
||||
@@ -138,7 +226,7 @@ partial class MainViewForm
|
||||
EntityTreeView.Dock = DockStyle.Fill;
|
||||
EntityTreeView.Location = new Point(0, 0);
|
||||
EntityTreeView.Name = "EntityTreeView";
|
||||
EntityTreeView.Size = new Size(495, 688);
|
||||
EntityTreeView.Size = new Size(467, 688);
|
||||
EntityTreeView.TabIndex = 0;
|
||||
//
|
||||
// DescriptionTextBox
|
||||
@@ -149,7 +237,7 @@ partial class MainViewForm
|
||||
DescriptionTextBox.Name = "DescriptionTextBox";
|
||||
DescriptionTextBox.ReadOnly = true;
|
||||
DescriptionTextBox.ScrollBars = ScrollBars.Vertical;
|
||||
DescriptionTextBox.Size = new Size(478, 688);
|
||||
DescriptionTextBox.Size = new Size(452, 688);
|
||||
DescriptionTextBox.TabIndex = 0;
|
||||
//
|
||||
// MainViewForm
|
||||
@@ -169,6 +257,8 @@ partial class MainViewForm
|
||||
((System.ComponentModel.ISupportInitialize) InnerSplitContainer).EndInit();
|
||||
InnerSplitContainer.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize) EntityGridView).EndInit();
|
||||
PaginationPagel.ResumeLayout(false);
|
||||
PaginationPagel.PerformLayout();
|
||||
ResultSplitContainer.Panel1.ResumeLayout(false);
|
||||
ResultSplitContainer.Panel2.ResumeLayout(false);
|
||||
ResultSplitContainer.Panel2.PerformLayout();
|
||||
@@ -186,4 +276,11 @@ partial class MainViewForm
|
||||
private TreeView EntityTreeView;
|
||||
private SplitContainer ResultSplitContainer;
|
||||
private TextBox DescriptionTextBox;
|
||||
private Panel PaginationPagel;
|
||||
private Button LastPageButton;
|
||||
private Button NextPageButton;
|
||||
private Button PrevPageButton;
|
||||
private Button FirstPageButton;
|
||||
private TextBox PageTextBox;
|
||||
private TextBox PaginationLabel;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Pf2eModel;
|
||||
using Pf2eModel.Model;
|
||||
using Pf2eModel.Model.Base;
|
||||
@@ -29,10 +31,32 @@ public partial class MainViewForm : Form
|
||||
TypesListBox.SelectedIndex = 0;
|
||||
}
|
||||
|
||||
private void TypesListBox_SelectedIndexChanged(object sender, EventArgs _)
|
||||
public const int PerPage = 20;
|
||||
|
||||
public int Count;
|
||||
|
||||
public int Page
|
||||
{
|
||||
if (TypesListBox.SelectedItem is null)
|
||||
get => Convert.ToInt32(PageTextBox.Text);
|
||||
set
|
||||
{
|
||||
PageTextBox.Text = value.ToString();
|
||||
UpdateTreeView();
|
||||
}
|
||||
}
|
||||
|
||||
public int MaxPage => Convert.ToInt32(Math.Ceiling(1.0 * Count / PerPage));
|
||||
|
||||
|
||||
private void UpdateTreeView()
|
||||
{
|
||||
EntityType type = (EntityType) TypesListBox.SelectedItem!;
|
||||
|
||||
Count = Context.Entities.Count(e => e.Type == type);
|
||||
|
||||
if (Page < 1 || Page > MaxPage)
|
||||
{
|
||||
Page = Math.Min(MaxPage, Math.Max(1, Page));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -40,15 +64,71 @@ public partial class MainViewForm : Form
|
||||
.Where(e => e.Type == (EntityType) TypesListBox.SelectedItem)
|
||||
.OrderBy(e => e.Id)
|
||||
.Include(e => e.Sources)
|
||||
.ThenInclude(s => s.Source)
|
||||
.Include(e => e.Aliases)
|
||||
.Include(e => e.Keywords)
|
||||
.Include(e => e.Externals)
|
||||
.ThenInclude(x => x.Target)
|
||||
.Include(e => e.Traits)
|
||||
.ThenInclude(t => t.Entity)
|
||||
.Select(e => new EntityGridRow(e))
|
||||
.Skip((Page - 1) * PerPage)
|
||||
.Take(PerPage)
|
||||
.ToList();
|
||||
|
||||
EntityGridView.Rows[0].Selected = true;
|
||||
|
||||
PaginationLabel.Text = $"Всего: {Count} объектов, {MaxPage} страниц";
|
||||
|
||||
FirstPageButton.Enabled = Page > 1;
|
||||
PrevPageButton.Enabled = Page > 1;
|
||||
NextPageButton.Enabled = Page < MaxPage;
|
||||
LastPageButton.Enabled = Page < MaxPage;
|
||||
}
|
||||
|
||||
private void TypesListBox_SelectedIndexChanged(object sender, EventArgs _)
|
||||
{
|
||||
if (TypesListBox.SelectedItem is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Page = 1;
|
||||
}
|
||||
private void FirstPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Page = 1;
|
||||
}
|
||||
|
||||
private void PrevPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Page--;
|
||||
}
|
||||
|
||||
private void NextPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Page++;
|
||||
}
|
||||
|
||||
private void LastPageButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
Page = MaxPage;
|
||||
}
|
||||
|
||||
private void PageTextBox_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar))
|
||||
{
|
||||
e.Handled = true;
|
||||
}
|
||||
|
||||
if (e.KeyChar == (char) Keys.Return)
|
||||
{
|
||||
UpdateTreeView();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void EntityGridView_RowStateChanged(object sender, DataGridViewRowStateChangedEventArgs e)
|
||||
{
|
||||
int rowsCount = EntityGridView.SelectedRows.Count;
|
||||
@@ -72,18 +152,31 @@ public partial class MainViewForm : Form
|
||||
{
|
||||
JsonSerializerSettings settings = new()
|
||||
{
|
||||
Converters = [new EntityConverter()]
|
||||
Converters = [
|
||||
new EntityConverter(),
|
||||
new StringEnumConverter { NamingStrategy = new CamelCaseNamingStrategy() },
|
||||
]
|
||||
};
|
||||
|
||||
string result = JsonConvert.SerializeObject(entity, settings);
|
||||
|
||||
Type type = EntityOfTypeAttribute.Resolve(entity);
|
||||
string subResult = JsonConvert.SerializeObject(Context.Find(type, entity.Id), settings);
|
||||
string subResult = JsonConvert.SerializeObject(ResolveEntity(entity), settings);
|
||||
|
||||
return result[..^1] + $",\"SubEntity\":{subResult}}}";
|
||||
}
|
||||
|
||||
public IEntity? ResolveEntity(Entity entity)
|
||||
{
|
||||
switch (entity.Type)
|
||||
{
|
||||
case EntityType.Ancestry:
|
||||
return Context.Ancestries
|
||||
.FirstOrDefault(e => e.Id == entity.Id);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void JsonToTreeview(TreeView treeView, string jsonString, string rootName)
|
||||
{
|
||||
@@ -92,11 +185,11 @@ public partial class MainViewForm : Form
|
||||
: JObject.Parse(jsonString);
|
||||
|
||||
treeView.Nodes.Clear();
|
||||
|
||||
foreach (TreeNode node in Element2TreeNode(json, rootName).Nodes)
|
||||
{
|
||||
treeView.Nodes.Add(node);
|
||||
}
|
||||
treeView.ExpandAll();
|
||||
}
|
||||
|
||||
private static TreeNode Element2TreeNode(object element, string text = "")
|
||||
@@ -156,4 +249,5 @@ public partial class MainViewForm : Form
|
||||
public Entity GetEntity() => _e;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user