feat: implement part type management and searchable combo box in property editor
This commit is contained in:
parent
f13d646f7d
commit
0d55a38c86
|
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"dotnet.preferCSharpExtension": true
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Laservall.Solidworks.Common
|
||||||
|
{
|
||||||
|
public class PartTypeItem
|
||||||
|
{
|
||||||
|
[JsonProperty("type_id")]
|
||||||
|
public string TypeId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("parent_type_id")]
|
||||||
|
public string ParentTypeId { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("code")]
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("type_name")]
|
||||||
|
public string TypeName { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("type_key")]
|
||||||
|
public string TypeKey { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("is_child")]
|
||||||
|
public string IsChild { get; set; }
|
||||||
|
|
||||||
|
public string DisplayText => $"{Code} - {TypeName}";
|
||||||
|
|
||||||
|
public override string ToString() => DisplayText;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PLMService
|
||||||
|
{
|
||||||
|
private const string PartTypeSearchUrl = "http://10.0.0.155:9992/api/PLM/PartType/Search";
|
||||||
|
private static readonly HttpClient _httpClient = new HttpClient { Timeout = TimeSpan.FromSeconds(30) };
|
||||||
|
|
||||||
|
private static List<PartTypeItem> _cachedPartTypes;
|
||||||
|
private static readonly object _lock = new object();
|
||||||
|
|
||||||
|
public static List<PartTypeItem> CachedPartTypes
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
return _cachedPartTypes ?? new List<PartTypeItem>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<List<PartTypeItem>> SearchPartTypesAsync(string code = "", string name = "")
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var requestBody = new { code = code ?? "", name = name ?? "" };
|
||||||
|
var json = JsonConvert.SerializeObject(requestBody);
|
||||||
|
var content = new StringContent(json, Encoding.UTF8, "application/json-patch+json");
|
||||||
|
|
||||||
|
var response = await _httpClient.PostAsync(PartTypeSearchUrl, content).ConfigureAwait(false);
|
||||||
|
var responseText = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (!response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"PLM PartType/Search failed: {(int)response.StatusCode} {responseText}");
|
||||||
|
return new List<PartTypeItem>();
|
||||||
|
}
|
||||||
|
|
||||||
|
return JsonConvert.DeserializeObject<List<PartTypeItem>>(responseText)
|
||||||
|
?? new List<PartTypeItem>();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"PLM PartType/Search error: {ex.Message}");
|
||||||
|
return new List<PartTypeItem>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task LoadAndCachePartTypesAsync()
|
||||||
|
{
|
||||||
|
var items = await SearchPartTypesAsync("", "").ConfigureAwait(false);
|
||||||
|
lock (_lock)
|
||||||
|
{
|
||||||
|
_cachedPartTypes = items;
|
||||||
|
}
|
||||||
|
Debug.WriteLine($"PLM PartTypes loaded: {items.Count} items");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
using HandyControl.Controls;
|
using HandyControl.Controls;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
namespace Laservall.Solidworks.Common
|
namespace Laservall.Solidworks.Common
|
||||||
{
|
{
|
||||||
|
|
@ -35,7 +35,7 @@ namespace Laservall.Solidworks.Common
|
||||||
{
|
{
|
||||||
public override FrameworkElement CreateElement(PropertyItem propertyItem)
|
public override FrameworkElement CreateElement(PropertyItem propertyItem)
|
||||||
{
|
{
|
||||||
var comboBox = new ComboBox();
|
var comboBox = new System.Windows.Controls.ComboBox();
|
||||||
comboBox.IsEditable = true;
|
comboBox.IsEditable = true;
|
||||||
var items = ComboBoxDataRegistry.GetItems(propertyItem.DisplayName);
|
var items = ComboBoxDataRegistry.GetItems(propertyItem.DisplayName);
|
||||||
comboBox.ItemsSource = items;
|
comboBox.ItemsSource = items;
|
||||||
|
|
@ -49,29 +49,109 @@ namespace Laservall.Solidworks.Common
|
||||||
|
|
||||||
public override DependencyProperty GetDependencyProperty()
|
public override DependencyProperty GetDependencyProperty()
|
||||||
{
|
{
|
||||||
return ComboBox.SelectedItemProperty;
|
return System.Windows.Controls.ComboBox.SelectedItemProperty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CategoryComboxPropertyEditor : PropertyEditorBase
|
public class CategoryComboxPropertyEditor : PropertyEditorBase
|
||||||
{
|
{
|
||||||
|
private static List<PartTypeItem> _allPartTypes = new List<PartTypeItem>();
|
||||||
|
|
||||||
|
public static void SetPartTypes(List<PartTypeItem> items)
|
||||||
|
{
|
||||||
|
_allPartTypes = items ?? new List<PartTypeItem>();
|
||||||
|
}
|
||||||
|
|
||||||
public override FrameworkElement CreateElement(PropertyItem propertyItem)
|
public override FrameworkElement CreateElement(PropertyItem propertyItem)
|
||||||
{
|
{
|
||||||
var comboBox = new ComboBox();
|
var comboBox = new System.Windows.Controls.ComboBox
|
||||||
comboBox.IsEditable = true;
|
{
|
||||||
var items = ComboBoxDataRegistry.GetItems(propertyItem.DisplayName);
|
IsEditable = true,
|
||||||
comboBox.ItemsSource = items;
|
IsTextSearchEnabled = false
|
||||||
comboBox.SelectedItem = propertyItem.Value?.ToString();
|
};
|
||||||
|
|
||||||
|
var allItems = _allPartTypes;
|
||||||
|
|
||||||
|
comboBox.ItemsSource = allItems;
|
||||||
|
comboBox.DisplayMemberPath = "DisplayText";
|
||||||
|
comboBox.SelectedValuePath = "Code";
|
||||||
|
|
||||||
|
var currentCode = propertyItem.Value?.ToString();
|
||||||
|
if (!string.IsNullOrEmpty(currentCode))
|
||||||
|
{
|
||||||
|
var match = allItems.FirstOrDefault(x =>
|
||||||
|
string.Equals(x.Code, currentCode, StringComparison.OrdinalIgnoreCase));
|
||||||
|
if (match != null)
|
||||||
|
{
|
||||||
|
comboBox.SelectedItem = match;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool suppressFilter = false;
|
||||||
|
|
||||||
comboBox.SelectionChanged += (s, e) =>
|
comboBox.SelectionChanged += (s, e) =>
|
||||||
{
|
{
|
||||||
propertyItem.Value = comboBox.SelectedItem;
|
if (comboBox.SelectedItem is PartTypeItem selected)
|
||||||
|
{
|
||||||
|
propertyItem.Value = selected.Code;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
comboBox.Loaded += (s, e) =>
|
||||||
|
{
|
||||||
|
var textBox = comboBox.Template.FindName("PART_EditableTextBox", comboBox) as TextBox;
|
||||||
|
if (textBox == null) return;
|
||||||
|
|
||||||
|
textBox.TextChanged += (s2, e2) =>
|
||||||
|
{
|
||||||
|
if (suppressFilter) return;
|
||||||
|
|
||||||
|
var text = textBox.Text;
|
||||||
|
if (string.IsNullOrEmpty(text))
|
||||||
|
{
|
||||||
|
comboBox.ItemsSource = allItems;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var lower = text.ToLowerInvariant();
|
||||||
|
var filtered = allItems.Where(x =>
|
||||||
|
(x.Code != null && x.Code.ToLowerInvariant().Contains(lower)) ||
|
||||||
|
(x.TypeName != null && x.TypeName.ToLowerInvariant().Contains(lower))
|
||||||
|
).ToList();
|
||||||
|
comboBox.ItemsSource = filtered;
|
||||||
|
}
|
||||||
|
|
||||||
|
suppressFilter = true;
|
||||||
|
comboBox.IsDropDownOpen = true;
|
||||||
|
textBox.Text = text;
|
||||||
|
textBox.CaretIndex = text.Length;
|
||||||
|
suppressFilter = false;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.DropDownClosed += (s, e) =>
|
||||||
|
{
|
||||||
|
if (comboBox.SelectedItem is PartTypeItem selected)
|
||||||
|
{
|
||||||
|
suppressFilter = true;
|
||||||
|
var textBox = comboBox.Template.FindName("PART_EditableTextBox", comboBox) as TextBox;
|
||||||
|
if (textBox != null)
|
||||||
|
{
|
||||||
|
textBox.Text = selected.DisplayText;
|
||||||
|
textBox.CaretIndex = textBox.Text.Length;
|
||||||
|
}
|
||||||
|
suppressFilter = false;
|
||||||
|
|
||||||
|
comboBox.ItemsSource = allItems;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return comboBox;
|
return comboBox;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override DependencyProperty GetDependencyProperty()
|
public override DependencyProperty GetDependencyProperty()
|
||||||
{
|
{
|
||||||
return ComboBox.SelectedItemProperty;
|
return System.Windows.Controls.ComboBox.SelectedValueProperty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,7 @@
|
||||||
<Compile Include="AppDomainDllLoader.cs" />
|
<Compile Include="AppDomainDllLoader.cs" />
|
||||||
<Compile Include="Common\PLMConfig.cs" />
|
<Compile Include="Common\PLMConfig.cs" />
|
||||||
<Compile Include="Common\PropertyEditor.cs" />
|
<Compile Include="Common\PropertyEditor.cs" />
|
||||||
|
<Compile Include="Common\PartTypeService.cs" />
|
||||||
<Compile Include="Common\SM4Helper.cs" />
|
<Compile Include="Common\SM4Helper.cs" />
|
||||||
<Compile Include="Common\ViewModelBase.cs" />
|
<Compile Include="Common\ViewModelBase.cs" />
|
||||||
<Compile Include="Common\RelayCommand.cs" />
|
<Compile Include="Common\RelayCommand.cs" />
|
||||||
|
|
@ -169,8 +170,8 @@
|
||||||
<Import Project="packages\Xarial.XCad.SolidWorks.0.8.2\build\Xarial.XCad.SolidWorks.targets" Condition="Exists('packages\Xarial.XCad.SolidWorks.0.8.2\build\Xarial.XCad.SolidWorks.targets')" />
|
<Import Project="packages\Xarial.XCad.SolidWorks.0.8.2\build\Xarial.XCad.SolidWorks.targets" Condition="Exists('packages\Xarial.XCad.SolidWorks.0.8.2\build\Xarial.XCad.SolidWorks.targets')" />
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用"NuGet 程序包还原"可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Error Condition="!Exists('packages\Xarial.XCad.SolidWorks.0.8.2\build\Xarial.XCad.SolidWorks.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Xarial.XCad.SolidWorks.0.8.2\build\Xarial.XCad.SolidWorks.targets'))" />
|
<Error Condition="!Exists('packages\Xarial.XCad.SolidWorks.0.8.2\build\Xarial.XCad.SolidWorks.targets')" Text="$([System.String]::Format('$(ErrorText)', 'packages\Xarial.XCad.SolidWorks.0.8.2\build\Xarial.XCad.SolidWorks.targets'))" />
|
||||||
</Target>
|
</Target>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using HandyControl.Controls;
|
using HandyControl.Controls;
|
||||||
using Laservall.Solidworks.Common;
|
using Laservall.Solidworks.Common;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
@ -168,6 +168,21 @@ namespace Laservall.Solidworks.Model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private string _partType;
|
||||||
|
[Category("零件属性")]
|
||||||
|
[DisplayName("零件类型")]
|
||||||
|
[Editor(typeof(SearchableComboBoxPropertyEditor), typeof(SearchableComboBoxPropertyEditor))]
|
||||||
|
public string PartType
|
||||||
|
{
|
||||||
|
get => _partType;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (_partType == value) return;
|
||||||
|
_partType = value;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private bool _purCheck;
|
private bool _purCheck;
|
||||||
[Category("零件属性")]
|
[Category("零件属性")]
|
||||||
[DisplayName("采购检验")]
|
[DisplayName("采购检验")]
|
||||||
|
|
@ -211,4 +226,4 @@ namespace Laservall.Solidworks.Model
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ using Laservall.Solidworks.Model;
|
||||||
using SolidWorks.Interop.sldworks;
|
using SolidWorks.Interop.sldworks;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using Xarial.XCad;
|
using Xarial.XCad;
|
||||||
using Xarial.XCad.Documents;
|
using Xarial.XCad.Documents;
|
||||||
|
|
@ -37,8 +38,16 @@ namespace Laservall.Solidworks.Pane
|
||||||
set => Set(ref _versionText, value);
|
set => Set(ref _versionText, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool _isLoadingPartTypes;
|
||||||
|
public bool IsLoadingPartTypes
|
||||||
|
{
|
||||||
|
get => _isLoadingPartTypes;
|
||||||
|
set => Set(ref _isLoadingPartTypes, value);
|
||||||
|
}
|
||||||
|
|
||||||
public ICommand SaveCommand { get; }
|
public ICommand SaveCommand { get; }
|
||||||
public ICommand ResetCommand { get; }
|
public ICommand ResetCommand { get; }
|
||||||
|
public ICommand RefreshPartTypesCommand { get; }
|
||||||
|
|
||||||
public PartPropPaneViewModel()
|
public PartPropPaneViewModel()
|
||||||
{
|
{
|
||||||
|
|
@ -46,6 +55,45 @@ namespace Laservall.Solidworks.Pane
|
||||||
|
|
||||||
SaveCommand = new RelayCommand(ExecuteSave, CanSave);
|
SaveCommand = new RelayCommand(ExecuteSave, CanSave);
|
||||||
ResetCommand = new RelayCommand(ExecuteReset, CanReset);
|
ResetCommand = new RelayCommand(ExecuteReset, CanReset);
|
||||||
|
RefreshPartTypesCommand = new RelayCommand(async _ => await LoadPartTypesAsync());
|
||||||
|
|
||||||
|
// 异步加载零件类型数据
|
||||||
|
Task.Run(async () => await LoadPartTypesAsync());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从PLM API加载零件类型数据
|
||||||
|
/// </summary>
|
||||||
|
private async Task LoadPartTypesAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
IsLoadingPartTypes = true;
|
||||||
|
StatusText = "正在加载零件类型...";
|
||||||
|
|
||||||
|
// 调用PLM API获取零件类型
|
||||||
|
var partTypes = await PartTypeService.GetAllAsync();
|
||||||
|
|
||||||
|
if (partTypes.Count > 0)
|
||||||
|
{
|
||||||
|
// 注册到可搜索ComboBox编辑器
|
||||||
|
SearchableComboBoxPropertyEditor.RegisterPartTypes("零件类型", partTypes);
|
||||||
|
StatusText = $"已加载 {partTypes.Count} 个零件类型";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StatusText = "未找到零件类型数据";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (System.Exception ex)
|
||||||
|
{
|
||||||
|
Debug.WriteLine($"加载零件类型失败: {ex.Message}");
|
||||||
|
StatusText = "加载零件类型失败";
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsLoadingPartTypes = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnSelectionChanged(IXDocument doc, IXSelObject selObject)
|
public void OnSelectionChanged(IXDocument doc, IXSelObject selObject)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue