WPF 配置文件修改应用程序 - ConfigNX
ConfigNX - WPF 配置文件修改应用程序
项目概述
ConfigNX 是一个使用 WPF 开发的配置文件修改应用程序,利用 CommunityToolkit.Mvvm 8.1.0 和 Prism.DryIoc 8.1.97 库实现数据绑定、命令、视图模型和区域导航等功能。该应用程序用于管理测针、测头和机床的配置信息,提供添加、修改和删除操作。
程序架构
- 项目名称: ConfigNX
- 视图: MainView(主窗口)、Probe(测针)、Machine(机床)、ShowMach(显示机床详细信息)
- 视图模型: MainViewModel、ProbeViewModel、MachineViewModel、ShowMachViewModel
- 配置文件:
<OmvMachine>
<ProbeLibrary>
<Probe Name='RB-2.0-50-C' Diameter='2' Height='50'>\Configure\Model\RB-2.0-50-C.prt</Probe>
<Probe Name='RB-3.0-30-c' Diameter='3' Height='30'>\Configure\Model\RB-3.0-30-c.prt</Probe>
<Probe Name='RB-5.0-50-C' Diameter='6' Height='50'>\Configure\Model\RB-5.0-50-C.prt</Probe>
<Probe Name='RB-6.0-50-c' Diameter='6' Height='50'>\Configure\Model\RB-6.0-50-c.prt</Probe>
<Probe Name='RB-6.0-100-CF' Diameter='6' Height='100'>\Configure\Model\RB-6.0-100-CF.prt</Probe>
</ProbeLibrary>
<HeadLibrary>
<Head Name='REN-OMP40' Diameter='40' Height='50'>\Configure\Model\REN-OMP40.prt</Head>
<Head Name='REN-OMP60' Diameter='63' Height='76'>\Configure\Model\REN-OMP60.prt</Head>
<Head Name='heidenhain_01' Diameter='40' Height='50'>\Configure\Model\heidenhain_01.prt</Head>
</HeadLibrary>
<Machine Sel='T' Name='CNC-1' ID='101' Probe='RB-6.0-100-CF' Head='heidenhain_01'>
<Probe>RB-2.0-50-C</Probe>
<Probe>RB-5.0-50-C</Probe>
<Probe>RB-6.0-100-CF</Probe>
<Head>REN-OMP40</Head>
<Head>REN-heidenhain_01</Head>
</Machine>
<Machine Sel='F' Name='CNC-2' ID='102' Probe='RB-3.0-30-c' Head='REN-OMP60'>
<Probe>RB-3.0-30-c</Probe>
<Probe>RB-5.0-50-C</Probe>
<Probe>RB-6.0-50-c</Probe>
<Head>REN-OMP40</Head>
<Head>REN-OMP60</Head>
</Machine>
<Machine Sel='F' Name='CNC-6' ID='103' Probe='RB_4.0_50_CF' Head='REN-OMP40'>
<Probe>RB-3.0-30-c</Probe>
<Probe>RB-6.0-50-c</Probe>
<Probe>RB-6.0-100-CF</Probe>
<Head>REN-OMP40</Head>
<Head>REN-OMP60</Head>
</Machine>
</OmvMachine>
主要功能:
- 主窗口 (MainView)
- 包含一个 TabControl,有两个 TabItem:Probe 和 Machine。
- Probe TabItem: 使用 DataGrid 显示配置文件中的 ProbeLibrary 和 HeadLibrary。
- Machine TabItem: 使用 DataGrid 显示配置文件中的所有 Machine 项,每个 Machine 项包含 Probe 和 Head 选项,使用 ComboBox 表示。
- 显示机床详细信息窗口 (ShowMach)
- 通过 MainView 中 Machine DataGrid 的 ContextMenu 弹出,用于添加、修改和删除 Machine 项。
数据结构:
public class ProbeCfg
{
public string? Name { get; set; }
public string? Diameter { get; set; }
public string? Height { get; set; }
public string? ModelPath { get; set; }
}
public class OmvMachine
{
public int MachID { get; set; }
public string? Name { get; set; }
public string? ProbeName; //测针类型
public string? HeadName; //测头类型
public string? ProbeD; //测针直径
public string? ProbeH; //测针高度
public List<string>? ProbeOpt; //测针选项
public List<string>? HeadOpt; //测头选项
public List<string>? ChuckOpt; //工作台选项
}
public partial class MachData : ObservableObject
{
public List<ProbeCfg> ProbeLib;//测针库
public List<ProbeCfg> HeadLib;//测头库
public List<OmvMachine> MachLib;//机床库
}
视图模型:
public partial class MainViewModel : ObservableObject
public partial class MachineViewModel : ObservableRecipient, IRecipient<ValueChangedMessage<string>>
public partial class ProbeViewModel : ObservableObject
public partial class ShowMachViewModel : ObservableObject,IDialogAware
代码示例:
MainView.xaml
<Window x:Class="ConfigNX.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
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"
xmlns:local="clr-namespace:ConfigNX"
xmlns:controls="clr-namespace:Microsoft.Toolkit.Wpf.UI.Controls;assembly=Microsoft.Toolkit.Wpf.UI.Controls"
xmlns:prism="http://prismlibrary.com/"
mc:Ignorable="d"
Title="ConfigNX" Height="450" Width="800">
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<TabControl prism:RegionManager.RegionName="MainRegion">
<TabItem Header="Probe">
<controls:DataGrid ItemsSource="{Binding ProbeLib}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="Diameter" Binding="{Binding Diameter}"/>
<DataGridTextColumn Header="Height" Binding="{Binding Height}"/>
<DataGridTextColumn Header="Model Path" Binding="{Binding ModelPath}"/>
</DataGrid.Columns>
</controls:DataGrid>
</TabItem>
<TabItem Header="Machine">
<controls:DataGrid ItemsSource="{Binding MachLib}" AutoGenerateColumns="False"
SelectionMode="Single" SelectionUnit="FullRow"
prism:ViewModelLocator.AutoWireViewModel="True"
ContextMenuOpening="DataGrid_ContextMenuOpening">
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem Header="Add" Command="{Binding AddCommand}"/>
<MenuItem Header="Modify" Command="{Binding ModifyCommand}"
CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
<MenuItem Header="Delete" Command="{Binding DeleteCommand}"
CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</ContextMenu>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn Header="MachID" Binding="{Binding MachID}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
<DataGridTextColumn Header="ProbeName" Binding="{Binding ProbeName}"/>
<DataGridTextColumn Header="HeadName" Binding="{Binding HeadName}"/>
<DataGridTextColumn Header="ProbeD" Binding="{Binding ProbeD}"/>
<DataGridTextColumn Header="ProbeH" Binding="{Binding ProbeH}"/>
<DataGridTemplateColumn Header="ProbeOpt">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ProbeOpt}" SelectedItem="{Binding ProbeName}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="HeadOpt">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding HeadOpt}" SelectedItem="{Binding HeadName}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="ChuckOpt">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding ChuckOpt}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</controls:DataGrid>
</TabItem>
</TabControl>
</Grid>
</Window>
MainViewModel.cs
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Microsoft.Toolkit.Mvvm.Input;
using Prism.Commands;
using Prism.Regions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace ConfigNX.ViewModels
{
public partial class MainViewModel : ObservableObject
{
private readonly IRegionManager _regionManager;
private readonly MachData _machData;
public MainViewModel(IRegionManager regionManager, MachData machData)
{
_regionManager = regionManager;
_machData = machData;
}
public ObservableCollection<ProbeCfg> ProbeLib => new ObservableCollection<ProbeCfg>(_machData.ProbeLib);
public ObservableCollection<OmvMachine> MachLib => new ObservableCollection<OmvMachine>(_machData.MachLib);
public DelegateCommand AddCommand => new DelegateCommand(AddMachine);
public DelegateCommand<OmvMachine> ModifyCommand => new DelegateCommand<OmvMachine>(ModifyMachine);
public DelegateCommand<OmvMachine> DeleteCommand => new DelegateCommand<OmvMachine>(DeleteMachine);
private void AddMachine()
{
_regionManager.RequestNavigate("MainRegion", "ShowMach", new NavigationParameters
{
{"Title", "Add Machine" },
{"Action", "Add" },
{"MachData", _machData }
});
}
private void ModifyMachine(OmvMachine machine)
{
_regionManager.RequestNavigate("MainRegion", "ShowMach", new NavigationParameters
{
{"Title", "Modify Machine" },
{"Action", "Modify" },
{"MachData", _machData },
{"Machine", machine }
});
}
private void DeleteMachine(OmvMachine machine)
{
_machData.MachLib.Remove(machine);
}
}
}
MachineViewModel.cs
using ConfigNX.Models;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Prism.Commands;
using Prism.Regions;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
namespace ConfigNX.ViewModels
{
public partial class MachineViewModel : ObservableRecipient, IRecipient<ValueChangedMessage<string>>
{
private readonly IRegionManager _regionManager;
private readonly MachData _machData;
public MachineViewModel(IRegionManager regionManager, MachData machData)
{
_regionManager = regionManager;
_machData = machData;
}
public ObservableCollection<string> ProbeOpt => new ObservableCollection<string>(_machData.ProbeLib.Select(p => p.Name));
public ObservableCollection<string> HeadOpt => new ObservableCollection<string>(_machData.HeadLib.Select(h => h.Name));
public ObservableCollection<string> ChuckOpt => new ObservableCollection<string>(new List<string> { "A", "B", "C" });
public void OnReceived(ValueChangedMessage<string> message)
{
if (message.Key == "ProbeName")
{
var machine = _machData.MachLib.FirstOrDefault(m => m.ProbeName == message.OldValue);
if (machine != null)
{
machine.ProbeName = message.NewValue;
}
}
else if (message.Key == "HeadName")
{
var machine = _machData.MachLib.FirstOrDefault(m => m.HeadName == message.OldValue);
if (machine != null)
{
machine.HeadName = message.NewValue;
}
}
}
public void SaveMachine(OmvMachine machine)
{
if (_machData.MachLib.Contains(machine))
{
// modify machine
}
else
{
// add machine
}
_regionManager.RequestNavigate("MainRegion", "Machine");
}
}
}
ProbeViewModel.cs
using ConfigNX.Models;
using Microsoft.Toolkit.Mvvm.ComponentModel;
namespace ConfigNX.ViewModels
{
public partial class ProbeViewModel : ObservableObject
{
private readonly MachData _machData;
public ProbeViewModel(MachData machData)
{
_machData = machData;
}
}
}
ShowMach.xaml
<UserControl x:Class="ConfigNX.ShowMach"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ConfigNX"
xmlns:prism="http://prismlibrary.com/"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
prism:ViewModelLocator.AutoWireViewModel="True">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Label Content="MachID:" Grid.Column="0" Grid.Row="0" Margin="5"/>
<TextBox Text="{Binding Machine.MachID, Mode=TwoWay}" Grid.Column="1" Grid.Row="0" Margin="5"/>
<Label Content="Name:" Grid.Column="0" Grid.Row="1" Margin="5"/>
<TextBox Text="{Binding Machine.Name, Mode=TwoWay}" Grid.Column="1" Grid.Row="1" Margin="5"/>
<Label Content="Probe:" Grid.Column="0" Grid.Row="2" Margin="5"/>
<ComboBox ItemsSource="{Binding ProbeOpt}" SelectedItem="{Binding Machine.ProbeName, Mode=TwoWay}"
Grid.Column="1" Grid.Row="2" Margin="5"/>
<Label Content="Head:" Grid.Column="0" Grid.Row="3" Margin="5"/>
<ComboBox ItemsSource="{Binding HeadOpt}" SelectedItem="{Binding Machine.HeadName, Mode=TwoWay}"
Grid.Column="1" Grid.Row="3" Margin="5"/>
<Label Content="ProbeD:" Grid.Column="0" Grid.Row="4" Margin="5"/>
<TextBox Text="{Binding Machine.ProbeD, Mode=TwoWay}" Grid.Column="1" Grid.Row="4" Margin="5"/>
<Label Content="ProbeH:" Grid.Column="0" Grid.Row="5" Margin="5"/>
<TextBox Text="{Binding Machine.ProbeH, Mode=TwoWay}" Grid.Column="1" Grid.Row="5" Margin="5"/>
<Label Content="ProbeOpt:" Grid.Column="0" Grid.Row="6" Margin="5"/>
<ListBox ItemsSource="{Binding Machine.ProbeOpt}" SelectedItem="{Binding ProbeOptSelectedItem}"
Grid.Column="1" Grid.Row="6" Margin="5"/>
<Button Content="Add" Command="{Binding AddProbeOptCommand}" Grid.Column="1" Grid.Row="7" Margin="5"/>
<Button Content="Delete" Command="{Binding DeleteProbeOptCommand}" Grid.Column="1" Grid.Row="8" Margin="5"/>
<Label Content="HeadOpt:" Grid.Column="0" Grid.Row="9" Margin="5"/>
<ListBox ItemsSource="{Binding Machine.HeadOpt}" SelectedItem="{Binding HeadOptSelectedItem}"
Grid.Column="1" Grid.Row="9" Margin="5"/>
<Button Content="Add" Command="{Binding AddHeadOptCommand}" Grid.Column="1" Grid.Row="10" Margin="5"/>
<Button Content="Delete" Command="{Binding DeleteHeadOptCommand}" Grid.Column="1" Grid.Row="11" Margin="5"/>
<StackPanel Grid.Column="1" Grid.Row="18" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="Cancel" Command="{Binding CancelCommand}" Margin="5"/>
<Button Content="OK" Command="{Binding SaveCommand}" Margin="5"/>
</StackPanel>
</Grid>
</Grid>
</UserControl>
ShowMachViewModel.cs
using ConfigNX.Models;
using Microsoft.Toolkit.Mvvm.ComponentModel;
using Prism.Commands;
using Prism.Regions;
using System.Collections.ObjectModel;
namespace ConfigNX.ViewModels
{
public partial class ShowMachViewModel : ObservableObject, IDialogAware
{
private readonly IRegionManager _regionManager;
private readonly MachData _machData;
private string? _title;
private string? _action;
private OmvMachine? _machine;
public ShowMachViewModel(IRegionManager regionManager, MachData machData)
{
_regionManager = regionManager;
_machData = machData;
AddProbeOptCommand = new DelegateCommand(AddProbeOpt);
DeleteProbeOptCommand = new DelegateCommand(DeleteProbeOpt);
AddHeadOptCommand = new DelegateCommand(AddHeadOpt);
DeleteHeadOptCommand = new DelegateCommand(DeleteHeadOpt);
SaveCommand = new DelegateCommand(SaveMachine);
CancelCommand = new DelegateCommand(Cancel);
}
public ObservableCollection<string> ProbeOpt => new ObservableCollection<string>(_machData.ProbeLib.Select(p => p.Name));
public ObservableCollection<string> HeadOpt => new ObservableCollection<string>(_machData.HeadLib.Select(h => h.Name));
public OmvMachine? Machine
{
get => _machine;
set => SetProperty(ref _machine, value);
}
public string? Title
{
get => _title;
set => SetProperty(ref _title, value);
}
public string? Action
{
get => _action;
set => SetProperty(ref _action, value);
}
public bool CanCloseDialog => true;
public string? ProbeOptSelectedItem
{
get; set;
}
public string? HeadOptSelectedItem
{
get; set;
}
public DelegateCommand AddProbeOptCommand { get; }
public DelegateCommand DeleteProbeOptCommand { get; }
public DelegateCommand AddHeadOptCommand { get; }
public DelegateCommand DeleteHeadOptCommand { get; }
public DelegateCommand SaveCommand { get; }
public DelegateCommand CancelCommand { get; }
public void OnDialogClosed() { }
public void OnDialogOpened(NavigationParameters parameters)
{
Title = parameters.GetValue<string>("Title");
Action = parameters.GetValue<string>("Action");
MachData machData = parameters.GetValue<MachData>("MachData");
if (Action == "Modify")
{
Machine = parameters.GetValue<OmvMachine>("Machine");
}
else
{
Machine = new OmvMachine();
}
}
private void AddProbeOpt()
{
if (Machine != null)
{
Machine.ProbeOpt?.Add(ProbeOptSelectedItem);
}
}
private void DeleteProbeOpt()
{
if (Machine != null)
{
Machine.ProbeOpt?.Remove(ProbeOptSelectedItem);
}
}
private void AddHeadOpt()
{
if (Machine != null)
{
Machine.HeadOpt?.Add(HeadOptSelectedItem);
}
}
private void DeleteHeadOpt()
{
if (Machine != null)
{
Machine.HeadOpt?.Remove(HeadOptSelectedItem);
}
}
private void SaveMachine()
{
if (Machine != null && Action == "Add")
{
_machData.MachLib.Add(Machine);
}
_regionManager.RequestNavigate("MainRegion", "Machine");
}
private void Cancel()
{
_regionManager.RequestNavigate("MainRegion", "Machine");
}
}
}
注意:
- 上述代码示例省略了命名空间的引用。
- 该应用程序尚未实现配置文件的读写功能,需要根据具体需求添加相应的代码。
- 应用程序的 UI 设计和具体功能实现可以根据实际情况进行调整。
其他:
- 使用 CommunityToolkit.Mvvm 库可以方便地实现数据绑定、命令、事件等功能。
- 使用 Prism.DryIoc 库可以实现依赖注入,简化应用程序的开发过程。
- 使用 Prism.Regions 库可以实现区域导航,将应用程序的 UI 拆分为多个模块,提高代码的可维护性。
总结
ConfigNX 是一个使用 WPF 开发的简单配置文件修改应用程序,可以根据实际需求进行扩展和完善。该应用程序可以作为学习 WPF、CommunityToolkit.Mvvm、Prism.DryIoc 和 Prism.Regions 库的参考示例。
项目地址: (您需要提供一个项目地址)
欢迎讨论: (您需要提供一个讨论区链接)
原文地址: https://www.cveoy.top/t/topic/nTxg 著作权归作者所有。请勿转载和采集!