Step Present Preference Page
The model UserEnv is from its parent component. The UserEnv.UserConfig is rapidly used.
The model of Candidate Keys Panel is CandidateStepPresentKeyList. The model of Displayed Keys Panel is DisplayedStepPresentKeyList.
Layout
- Step Present Preference Page (or window)
- Candidate Keys Panel
- Category A Panel
- Key a ToggleButton
- Key b ToggleButton
- ...
- Category B Panel
- ...
- ...
- Category Other Panel
- Category A Panel
- Displayed Keys Panel
- Key 1
- Key 2
- ...
- Candidate Keys Panel
The categories are not defined for programming logic but only for user experience. So decide and define the categories in the GUI here only.
Since the Keys are not all come from the properties of MachiningStep, a category panel (Category Other Panel) for the uncategoried keys is required.
The keys in the Displayed Keys Panel is in sequence of DisplayedStepPresentKeyList. User tune the sequence and remove key by the Displayed Keys Panel. User add and remove the key from the ToggleButtons in Candidate Keys Panel. Those UI control items are required.
To both Candidate Keys Panel and Displayed Keys Panel: Apply PresentAttribute.Name as Key label by StepPresentAccessDictionary. Apply the key to the button tooltip.
The resx of MachiningStep contains the translation of PresentAttribute.Name, apply the translation to the GUI. If the translation not existed, use the original value.
Categories
Refer the code to design Categories:
@using Hi.Common
@using Hi.Geom
@using Hi.Mech.Topo
@{
string pCalss = "d-flex flex-wrap gap-2";
string cardTextClass = $"card-text {pCalss}";
}
<div class="card" style="overflow-y: hidden; height:100%; ">
<div style="overflow-y: scroll; ">
<div style="height: auto">
<div class="card-header py-0" data-bs-toggle="collapse" data-bs-target="#fileLineFlagTime-@Tid">@Loc["File"] / @Loc["Command"] / @Loc["Flag"] / @Loc["Time"] / @Loc["System"]</div>
<div class="collapse show " id="fileLineFlagTime-@Tid">
<div class="card-body ">
<div class="@cardTextClass">
<div class="w-auto" title="@Loc["File No."] : @Loc["Line No."]">
<span class="form-label">@Loc["F.L.No."]</span>
<span class="form-control readonly w-auto">@MillingStep?.FileNo : @MillingStep?.LineNo</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["File"]</span>
<span class="form-control readonly w-auto">@MillingStep?.FilePath</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Accumulated Time"]</span>
<span class="form-control readonly w-auto">@(MillingStep?.AccumulatedTime.ToString("G"))</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Line Text"]</span>
<span class="form-control readonly w-auto">@MillingStep?.LineText</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Flags"]</span>
<span class="form-control readonly w-auto">@MillingStep?.FlagsText</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Step Index"]</span>
<span class="form-control readonly w-auto">@MillingStep?.StepIndex</span>
</div>
</div>
</div>
</div>
<div class="card-header py-0" data-bs-toggle="collapse" data-bs-target="#toolFeedrateSpindleSpeed-@Tid">@Loc["Tool"] / @Loc["Feedrate"] / @Loc["Spindle Speed"]</div>
<div class="collapse show " id="toolFeedrateSpindleSpeed-@Tid">
<div class="card-body ">
<div class="@cardTextClass">
<div class="w-auto" title="@Loc["Tool ID"]">
<span class="form-label">@Loc["T"]</span>
<span class="form-control readonly w-auto">@MillingStep?.ToolId</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["S"] (rpm)</span>
<span class="form-control readonly w-auto">@(MillingStep?.SpindleSpeed_rpm.ToString("G5"))</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["F"] (mm/min)</span>
<span class="form-control readonly w-auto">@(MillingStep?.Feedrate_mmdmin.ToString("G5"))</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Feed per Tooth"] (mm)</span>
<span class="form-control readonly w-auto">@(MillingStep?.FeedPerTooth_mm.ToString("G5"))</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Feed per Cycle"] (mm)</span>
<span class="form-control readonly w-auto">@(MillingStep?.FeedPerCycle_mm.ToString("G5"))</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Tooth Arc Duration"] (s)</span>
<span class="form-control readonly w-auto">@(MillingStep?.ToothArcDuration_s.ToString("G4"))</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Spindle Cycle Period"] (s)</span>
<span class="form-control readonly w-auto">@(MillingStep?.SpindleCyclePeriod_s.ToString("G4"))</span>
</div>
<div class="w-auto">
<span class="form-label">@Loc["Cutting Speed"] (mm/s)</span>
<span class="form-control readonly w-auto">@(MillingStep?.CuttingSpeed_mmds?.ToString("G4"))</span>
</div>
</div>
</div>
</div>
<div class="card-header py-0" data-bs-toggle="collapse" data-bs-target="#coordinateAndMove-@Tid">@Loc["Coordinate"] / @Loc["Move"]</div>
<div class="collapse show " id="coordinateAndMove-@Tid">
<div class="card-body ">
<div class="@cardTextClass">
<p class="@pCalss">
@{
var mcCodes = HostMachiningProject?.MachiningEquipment?.GetMachiningChain()?.McCodes;
if (mcCodes != null)
{
var mcTransformers = HostMachiningProject
?.MachiningEquipment?.GetMachiningChain()?.McTransformers;
for (int i = 0; i < mcCodes.Length; i++)
{
if (mcTransformers[i] == null)
continue;
if (mcTransformers[i] is DynamicRotation)
{
<div class="w-auto" title="@Loc["Machine Coordinate"] @mcCodes[i] (deg)">
<span class="form-label">MC.@mcCodes[i] (deg)</span>
<span class="form-control readonly w-auto">
@MillingStep?.GetMcValue(i)?.SelfInvoke(v => MathUtil.ToDeg(v)).ToString("F5")
</span>
</div>
}
else
{
<div class="w-auto" title="@Loc["Machine Coordinate"] @mcCodes[i] (mm)">
<span class="form-label">MC.@mcCodes[i] (mm)</span>
<span class="form-control readonly w-auto">
@MillingStep?.GetMcValue(i)?.ToString("F5")
</span>
</div>
}
}
}
}
</p>
<div class="w-auto" title="@Loc["Cutter Location Point"]">
<span class="form-label">CL.XYZ (mm)</span>
<span class="form-control readonly w-auto">@(MillingStep?.Cl?.Point?.ToString("F5"))</span>
</div>
<div class="w-auto" title="@Loc["Cutter Location Normal"]">
<span class="form-label">CL.IJK</span>
<span class="form-control readonly w-auto">@(MillingStep?.Cl?.Normal?.ToString("F5"))</span>
</div>
@{
var moveDirection = MillingStep?.MoveOnProgramCoordinate.GetNormalized();
<div class="w-auto" title="@Loc["Move Direction"] (@Loc["Workpiece Coordinate"])">
<span class="form-label">@Loc["Move Direction"] [W]</span>
<span class="form-control readonly w-auto">@(moveDirection?.ToString("F4"))</span>
</div>
}
</div>
</div>
</div>
<div class="card-header py-0" data-bs-toggle="collapse" data-bs-target="#gcgr-@Tid">@Loc["Cutting Geometry"] / @Loc["Chip"] / @Loc["Bias"] / @Loc["Roughness"]</div>
<div class="collapse show " id="gcgr-@Tid">
<div class="card-body ">
<div class="@cardTextClass">
<div class="w-auto" title="@Loc["Is Touched"]">
<span class="form-label">@Loc["Is Touched"]</span>
<span class="form-control readonly w-auto">@Loc[(MillingStep?.IsTouched)?.ToString()]</span>
</div>
<div class="w-auto" title="@Loc["Cutting Width"]">
<span class="form-label">ae (mm)</span>
<span class="form-control readonly w-auto">@(MillingStep?.CuttingWidth_mm.ToString("G3"))</span>
</div>
<div class="w-auto" title="@Loc["Cutting Depth"]">
<span class="form-label">ap (mm)</span>
<span class="form-control readonly w-auto">@(MillingStep?.CuttingDepth_mm.ToString("G3"))</span>
</div>
<div class="w-auto" title="@Loc["Material Removal Rate"]">
<span class="form-label">MRR (mm<sup>3</sup>/s)</span>
<span class="form-control readonly w-auto">@(MillingStep?.Mrr_mm3ds.ToString("G3"))</span>
</div>
<div class="w-auto" title="@Loc["Chip Thickness"]">
<span class="form-label">@Loc["Chip Thickness"] (um)</span>
<span class="form-control readonly w-auto">@(MillingStep?.ChipThickness_um?.ToString("G3"))</span>
</div>
<div class="w-auto" title="@Loc["Chip Volume"]">
<span class="form-label">@Loc["Chip Volume"] (mm<sup>3</sup>)</span>
<span class="form-control readonly w-auto">@(MillingStep?.ChipVolume_mm3?.ToString("G3"))</span>
</div>
<div class="w-auto" title="@Loc["Chip Mass"]">
<span class="form-label">@Loc["Chip Mass"] (mg)</span>
<span class="form-control readonly w-auto">@(MillingStep?.ChipMass_mg?.ToString("G3"))</span>
</div>
<div class="w-auto" title="@Loc["Program Side Cusp"]">
<span class="form-label">@Loc["Program Side Cusp"] (um)</span>
<span class="form-control readonly w-auto">@(MillingStep?.ProgramSideCusp_um.ToString("G4"))</span>
</div>
<div class="w-auto" title="@Loc["Re-Cut Depth"]">
<span class="form-label">@Loc["Re-Cut Depth"] (um)</span>
<span class="form-control readonly w-auto">@(MillingStep?.ReCutDepth_um.ToString("G4"))</span>
</div>
<div class="w-auto" title="@Loc["Delta Tip Deflection"] (@Loc["Tool Running Coordinate"])">
<span class="form-label">@Loc["Delta Tip Deflection"] [TR] (um)</span>
<span class="form-control readonly w-auto">@(MillingStep?.DeltaTipDeflectionOnToolRunningCoordinate_um?.ToString("G3"))</span>
</div>
<div class="w-auto" title="@Loc["Max Tip Deflection"] (@Loc["Tool Running Coordinate"])">
<span class="form-label">@Loc["Max Tip Deflection"] [TR] (um)</span>
<span class="form-control readonly w-auto">@(MillingStep?.MaxTipDeflectionOnToolRunningCoordinate_um?.ToString("G3"))</span>
</div>
</div>
</div>
</div>
<div class="card-header py-0" data-bs-toggle="collapse" data-bs-target="#phe-@Tid">
@Loc["Mechanics"] / @Loc["Power"] / @Loc["Energy"]
</div>
<div class="collapse show " id="phe-@Tid">
<div class="card-body ">
<div class="@cardTextClass">
<div class="w-auto" title="@Loc["Max Force"]">
<span class="form-label">@Loc["Max Force"] (N)</span>
<span class="form-control readonly w-auto">@MillingStep?.MaxAbsForce_N?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Max Force"] (@Loc["Tool Running Coordinate"])">
<span class="form-label">@Loc["Max Force"] [TR] (N)</span>
<span class="form-control readonly w-auto">@MillingStep?.MaxForceOnToolRunningCoordinate_N?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Average Moment about Sensor"] (@Loc["Spindle Rotation Coordinate"])">
<span class="form-label">@Loc["Avg Moment about Sensor"] [SR] (Nm)</span>
<span class="form-control readonly w-auto">@MillingStep?.AvgMomentAboutSensor_Nm?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Average Absolute Moment about Sensor"] (@Loc["Spindle Rotation Coordinate"])">
<span class="form-label">@Loc["Avg Abs Moment about Sensor"] [SR] (Nm)</span>
<span class="form-control readonly w-auto">@MillingStep?.AvgAbsMomentAboutSensorVec3d_Nm?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Thermal Stress"]">
<span class="form-label">@Loc["Thermal Stress"] (MPa)</span>
<span class="form-control readonly w-auto">@MillingStep?.ThermalStress_MPa?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Workpiece Plastic Depth"]">
<span class="form-label">@Loc["Workpiece Plastic Depth"] (um)</span>
<span class="form-control readonly w-auto">@MillingStep?.WorkpiecePlasticDepth_um.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Spindle Input Power"]">
<span class="form-label">@Loc["Spindle Input Power"] (W)</span>
<span class="form-control readonly w-auto">@MillingStep?.SpindleInputPower_W.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Spindle Output Power"]">
<span class="form-label">@Loc["Spindle Output Power"] (W)</span>
<span class="form-control readonly w-auto">@MillingStep?.SpindleOutputPower_W.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Accumulated Spindle Energy Consumption From Spindle Input Power"]">
<span class="form-label">@Loc["Accumulated Spindle Energy Consumption"] (kWh)</span>
<span class="form-control readonly w-auto">@MillingStep?.AccumulatedSpindleEnergyConsumption_kWh.ToString("G6")</span>
</div>
</div>
</div>
</div>
<div class="card-header py-0" data-bs-toggle="collapse" data-bs-target="#tw-@Tid">@Loc["Temperature"] / @Loc["Wear"]</div>
<div class="collapse show " id="tw-@Tid">
<div class="card-body ">
<div class="@cardTextClass">
<div class="w-auto" title="@Loc["Chip Temperature"]">
<span class="form-label">@Loc["Chip Temperature"] (<sup>o</sup>C)</span>
<span class="form-control readonly w-auto">@MillingStep?.ChipTemperature_C?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Cutter Dermis Temperature"]">
<span class="form-label">@Loc["Cutter Dermis Temperature"] (<sup>o</sup>C)</span>
<span class="form-control readonly w-auto">@MillingStep?.CutterDermisTemperature_C?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Cutter Body Temperature"]">
<span class="form-label">@Loc["Cutter Body Temperature"] (<sup>o</sup>C)</span>
<span class="form-control readonly w-auto">@MillingStep?.CutterBodyTemperature_C?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Workpiece Dermis Temperature"]">
<span class="form-label">@Loc["Workpiece Dermis Temperature"] (<sup>o</sup>C)</span>
<span class="form-control readonly w-auto">@MillingStep?.WorkpieceDermisTemperature_C?.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Instant Crater Wear"]">
<span class="form-label">@Loc["Instant Crater Wear"] (um)</span>
<span class="form-control readonly w-auto">@MillingStep?.InstantCraterWear_um?.ToString("G3")</span>
</div>
<div class="w-auto" title="@Loc["Accumulated Crater Wear"]">
<span class="form-label">@Loc["Accumulated Crater Wear"] (um)</span>
<span class="form-control readonly w-auto">@MillingStep?.AccumulatedCraterWear_um.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Accumulated Flank Wear Depth"]">
<span class="form-label">@Loc["Accumulated Flank Wear Depth"] (um)</span>
<span class="form-control readonly w-auto">@MillingStep?.AccumulatedFlankWearDepth_um.ToString("G4")</span>
</div>
<div class="w-auto" title="@Loc["Accumulated Flank Wear Width"]">
<span class="form-label">VB (um)</span>
<span class="form-control readonly w-auto">@MillingStep?.AccumulatedFlankWearWidth_um.ToString("G4")</span>
</div>
</div>
</div>
</div>
<div class="card-header py-0" data-bs-toggle="collapse" data-bs-target="#custom-@Tid">@Loc["Custom"]</div>
<div class="collapse show " id="custom-@Tid">
<div class="card-body ">
<div class="@cardTextClass">
@{
var flexDictionary=MillingStep?.FlexDictionary;
if (flexDictionary != null)
{
foreach(var entry in flexDictionary)
{
if(HostMachiningProject?.StepPropertyAccessDictionary.TryGetValue(
entry.Key, out var stepPropertyAccess)==true)
{
<div class="w-auto" title="@(stepPropertyAccess.PresentAttribute?.Name)">
<span class="form-label">@(stepPropertyAccess.PresentAttribute?.ShortName)</span>
<span class="form-control readonly w-auto">@(stepPropertyAccess.GetValueText(MillingStep))</span>
</div>
}
else
{
<div class="w-auto" title="@(entry.Key) (@Loc["Not Registered"])">
<span class="form-label">@(entry.Key)</span>
<span class="form-control readonly w-auto">@(entry.Value)</span>
</div>
}
}
}
}
</div>
</div>
</div>
</div>
</div>
</div>
Refer the code to apply PresentAttribute.
internal static void ShowStepPresent(
UserEnv userEnv, MachiningStep machiningStep)
{
foreach (var entry in userEnv.DisplayedStepPresentAccessList)
{
var present = entry.Value.Present;
var valueText = string.Format("{0:" + present.DataFormatString + "}", entry.Value.GetValueFunc.Invoke(machiningStep));
Console.WriteLine($"{present.ShortName}: {valueText} {present.TailUnitString} ({present.Name} [{entry.Key}])");
}
}
Single-User WPF Application Source Code Path
- Preference/StepPresentPreferenceWindow
see this page for git repository.