增加只读访问
This commit is contained in:
@@ -20,26 +20,19 @@ namespace SpineViewer
|
|||||||
public PropertyGrid? PropertyGrid { get; set; }
|
public PropertyGrid? PropertyGrid { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spine 列表浅拷贝
|
/// 获取数组快照, 访问时必须使用 lock 语句锁定对象本身
|
||||||
|
/// </summary>
|
||||||
|
public readonly ReadOnlyCollection<Spine.Spine> Spines;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Spine 列表, 访问时必须使用 lock 语句锁定 Spines
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
|
|
||||||
[Browsable(false)]
|
|
||||||
public Spine.Spine[] Spines
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
dataMutex.WaitOne();
|
|
||||||
var shallowCopy = spines.ToArray();
|
|
||||||
dataMutex.ReleaseMutex();
|
|
||||||
return shallowCopy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private readonly List<Spine.Spine> spines = [];
|
private readonly List<Spine.Spine> spines = [];
|
||||||
private readonly Mutex dataMutex = new();
|
|
||||||
|
|
||||||
public SpineListView()
|
public SpineListView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
Spines = spines.AsReadOnly();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -47,10 +40,6 @@ namespace SpineViewer
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private void Insert(int index = -1)
|
private void Insert(int index = -1)
|
||||||
{
|
{
|
||||||
// 如果索引无效则在末尾添加
|
|
||||||
if (index < 0 || index > spines.Count)
|
|
||||||
index = spines.Count;
|
|
||||||
|
|
||||||
var dialog = new OpenSpineDialog();
|
var dialog = new OpenSpineDialog();
|
||||||
if (dialog.ShowDialog() != DialogResult.OK)
|
if (dialog.ShowDialog() != DialogResult.OK)
|
||||||
return;
|
return;
|
||||||
@@ -58,7 +47,13 @@ namespace SpineViewer
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var spine = Spine.Spine.New(dialog.Version, dialog.SkelPath, dialog.AtlasPath);
|
var spine = Spine.Spine.New(dialog.Version, dialog.SkelPath, dialog.AtlasPath);
|
||||||
spines.Insert(index, spine);
|
|
||||||
|
// 如果索引无效则在末尾添加
|
||||||
|
if (index < 0 || index > listView.Items.Count)
|
||||||
|
index = listView.Items.Count;
|
||||||
|
|
||||||
|
// 锁定外部的读操作
|
||||||
|
lock (Spines) { spines.Insert(index, spine); }
|
||||||
listView.Items.Insert(index, new ListViewItem([spine.Name, spine.Version.String()], -1) { ToolTipText = spine.SkelPath });
|
listView.Items.Insert(index, new ListViewItem([spine.Name, spine.Version.String()], -1) { ToolTipText = spine.SkelPath });
|
||||||
|
|
||||||
// 选中新增项
|
// 选中新增项
|
||||||
@@ -121,20 +116,8 @@ namespace SpineViewer
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var spine = Spine.Spine.New(version, skelPath);
|
var spine = Spine.Spine.New(version, skelPath);
|
||||||
// 对 spines 和 Items 的操作都要转到窗口线程操作
|
lock (Spines) { spines.Add(spine); }
|
||||||
if (listView.InvokeRequired)
|
listView.Invoke(() => listView.Items.Add(new ListViewItem([spine.Name, spine.Version.String()], -1) { ToolTipText = spine.SkelPath }));
|
||||||
{
|
|
||||||
listView.Invoke(() =>
|
|
||||||
{
|
|
||||||
spines.Add(spine);
|
|
||||||
listView.Items.Add(new ListViewItem([spine.Name, spine.Version.String()], -1) { ToolTipText = spine.SkelPath });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
spines.Add(spine);
|
|
||||||
listView.Items.Add(new ListViewItem([spine.Name, spine.Version.String()], -1) { ToolTipText = spine.SkelPath });
|
|
||||||
}
|
|
||||||
success++;
|
success++;
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
@@ -159,13 +142,15 @@ namespace SpineViewer
|
|||||||
{
|
{
|
||||||
if (PropertyGrid is not null)
|
if (PropertyGrid is not null)
|
||||||
{
|
{
|
||||||
|
lock (Spines)
|
||||||
if (listView.SelectedIndices.Count <= 0)
|
{
|
||||||
PropertyGrid.SelectedObject = null;
|
if (listView.SelectedIndices.Count <= 0)
|
||||||
else if (listView.SelectedIndices.Count <= 1)
|
PropertyGrid.SelectedObject = null;
|
||||||
PropertyGrid.SelectedObject = spines[listView.SelectedIndices[0]];
|
else if (listView.SelectedIndices.Count <= 1)
|
||||||
else
|
PropertyGrid.SelectedObject = spines[listView.SelectedIndices[0]];
|
||||||
PropertyGrid.SelectedObjects = listView.SelectedIndices.Cast<int>().Select(index => spines[index]).ToArray();
|
else
|
||||||
|
PropertyGrid.SelectedObjects = listView.SelectedIndices.Cast<int>().Select(index => spines[index]).ToArray();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,23 +197,29 @@ namespace SpineViewer
|
|||||||
// 获取拖放源项和目标项
|
// 获取拖放源项和目标项
|
||||||
var draggedItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
|
var draggedItem = (ListViewItem)e.Data.GetData(typeof(ListViewItem));
|
||||||
int draggedIndex = draggedItem.Index;
|
int draggedIndex = draggedItem.Index;
|
||||||
var draggedSpine = spines[draggedIndex];
|
|
||||||
|
|
||||||
var point = listView.PointToClient(new Point(e.X, e.Y));
|
var point = listView.PointToClient(new Point(e.X, e.Y));
|
||||||
var targetItem = listView.GetItemAt(point.X, point.Y);
|
var targetItem = listView.GetItemAt(point.X, point.Y);
|
||||||
int targetIndex = targetItem is null ? listView.Items.Count : targetItem.Index;
|
int targetIndex = targetItem is null ? listView.Items.Count : targetItem.Index;
|
||||||
|
|
||||||
if (targetIndex <= draggedIndex)
|
if (targetIndex <= draggedIndex)
|
||||||
{
|
{
|
||||||
spines.RemoveAt(draggedIndex);
|
lock (Spines)
|
||||||
spines.Insert(targetIndex, draggedSpine);
|
{
|
||||||
|
var draggedSpine = spines[draggedIndex];
|
||||||
|
spines.RemoveAt(draggedIndex);
|
||||||
|
spines.Insert(targetIndex, draggedSpine);
|
||||||
|
}
|
||||||
listView.Items.RemoveAt(draggedIndex);
|
listView.Items.RemoveAt(draggedIndex);
|
||||||
listView.Items.Insert(targetIndex, draggedItem);
|
listView.Items.Insert(targetIndex, draggedItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
spines.RemoveAt(draggedIndex);
|
lock (Spines)
|
||||||
spines.Insert(targetIndex - 1, draggedSpine);
|
{
|
||||||
|
var draggedSpine = spines[draggedIndex];
|
||||||
|
spines.RemoveAt(draggedIndex);
|
||||||
|
spines.Insert(targetIndex - 1, draggedSpine);
|
||||||
|
}
|
||||||
listView.Items.RemoveAt(draggedIndex);
|
listView.Items.RemoveAt(draggedIndex);
|
||||||
listView.Items.Insert(targetIndex - 1, draggedItem);
|
listView.Items.Insert(targetIndex - 1, draggedItem);
|
||||||
}
|
}
|
||||||
@@ -275,19 +266,16 @@ namespace SpineViewer
|
|||||||
if (listView.SelectedIndices.Count > 1)
|
if (listView.SelectedIndices.Count > 1)
|
||||||
{
|
{
|
||||||
if (MessageBox.Show($"确定移除所选 {listView.SelectedIndices.Count} 项吗?", "操作确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
|
if (MessageBox.Show($"确定移除所选 {listView.SelectedIndices.Count} 项吗?", "操作确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) != DialogResult.OK)
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var i in listView.SelectedIndices.Cast<int>().OrderByDescending(x => x))
|
foreach (var i in listView.SelectedIndices.Cast<int>().OrderByDescending(x => x))
|
||||||
{
|
{
|
||||||
spines.RemoveAt(i);
|
lock (Spines) { spines.RemoveAt(i); }
|
||||||
listView.Items.RemoveAt(i);
|
listView.Items.RemoveAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void toolStripMenuItem_MoveUp_Click(object sender, EventArgs e)
|
private void toolStripMenuItem_MoveUp_Click(object sender, EventArgs e)
|
||||||
{
|
{
|
||||||
if (listView.SelectedIndices.Count != 1)
|
if (listView.SelectedIndices.Count != 1)
|
||||||
@@ -296,7 +284,7 @@ namespace SpineViewer
|
|||||||
var index = listView.SelectedIndices[0];
|
var index = listView.SelectedIndices[0];
|
||||||
if (index > 0)
|
if (index > 0)
|
||||||
{
|
{
|
||||||
(spines[index - 1], spines[index]) = (spines[index], spines[index - 1]);
|
lock (Spines) { (spines[index - 1], spines[index]) = (spines[index], spines[index - 1]); }
|
||||||
var item = listView.Items[index];
|
var item = listView.Items[index];
|
||||||
listView.Items.RemoveAt(index);
|
listView.Items.RemoveAt(index);
|
||||||
listView.Items.Insert(index - 1, item);
|
listView.Items.Insert(index - 1, item);
|
||||||
@@ -309,9 +297,9 @@ namespace SpineViewer
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
var index = listView.SelectedIndices[0];
|
var index = listView.SelectedIndices[0];
|
||||||
if (index < spines.Count - 1)
|
if (index < listView.Items.Count - 1)
|
||||||
{
|
{
|
||||||
(spines[index], spines[index + 1]) = (spines[index + 1], spines[index]);
|
lock (Spines) { (spines[index], spines[index + 1]) = (spines[index + 1], spines[index]); }
|
||||||
var item = listView.Items[index + 1];
|
var item = listView.Items[index + 1];
|
||||||
listView.Items.RemoveAt(index + 1);
|
listView.Items.RemoveAt(index + 1);
|
||||||
listView.Items.Insert(index, item);
|
listView.Items.Insert(index, item);
|
||||||
@@ -325,7 +313,7 @@ namespace SpineViewer
|
|||||||
|
|
||||||
if (MessageBox.Show($"确认移除所有 {listView.Items.Count} 项吗?", "操作确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
|
if (MessageBox.Show($"确认移除所有 {listView.Items.Count} 项吗?", "操作确认", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
|
||||||
{
|
{
|
||||||
spines.Clear();
|
lock (Spines) { spines.Clear(); }
|
||||||
listView.Items.Clear();
|
listView.Items.Clear();
|
||||||
if (PropertyGrid is not null)
|
if (PropertyGrid is not null)
|
||||||
PropertyGrid.SelectedObject = null;
|
PropertyGrid.SelectedObject = null;
|
||||||
|
|||||||
Reference in New Issue
Block a user