在 VS2022 中创建 Presenter 文件对
在 VS2022 中创建 Presenter 文件对
一、ImagePresenter 的本质
ImagePresenter.xaml实际上是一个ResourceDictionary(资源字典),用于定义 DataTemplate,而不是标准的 UserControl 或 Window。
ImagePresenter.xaml → ResourceDictionary(定义 DataTemplate) ImagePresenter.xaml.cs → 对应的代码后台类(定义 ImagePresenter 类)二、创建方法
方法一:创建 ResourceDictionary + Class(推荐)
步骤 1:创建 XAML 文件
- 在 VS2022 中右键点击
Presenter文件夹 - 选择添加 → 新建项
- 搜索 “Resource Dictionary”
- 命名为
ImagePresenter.xaml - 点击添加
步骤 2:创建对应的 CS 文件
- 右键点击
Presenter文件夹 - 选择添加 → 新建项
- 搜索 “Class”
- 命名为
ImagePresenter.xaml.cs - 点击添加
方法二:手动创建(最简单)
直接在同一目录下创建两个文件:
Presenter/ ├── ImagePresenter.xaml ← ResourceDictionary └── ImagePresenter.xaml.cs ← ClassImagePresenter.xaml 内容:
<ResourceDictionaryxmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:local="clr-namespace:H.App.LabelImg"><!-- 在这里定义 DataTemplate --><DataTemplateDataType="{x:Type local:ImagePresenter}"><Grid><!-- 你的 UI 内容 --></Grid></DataTemplate></ResourceDictionary>ImagePresenter.xaml.cs 内容:
usingSystem;usingSystem.Collections.ObjectModel;usingH.Mvvm.ViewModels.Base;usingH.App.LabelImg.Provider;namespaceH.App.LabelImg;publicclassImagePresenter:ModelBindable<ImageBindable>{publicImagePresenter(ImageBindablet):base(t){}// 添加你的属性和命令}三、快速复制现有文件作为模板
如果你已经有类似的 Presenter 文件(如LabelManagerPresenter.xaml),可以:
- 复制
LabelManagerPresenter.xaml→ 重命名为ImagePresenter.xaml - 复制
LabelManagerPresenter.xaml.cs→ 重命名为ImagePresenter.xaml.cs - 修改文件内容
四、ImagePresenter 完整代码参考
根据你之前打开的文件,以下是完整的 ImagePresenter:
ImagePresenter.xaml.cs
usingH.App.LabelImg.Provider;usingH.Extensions.Common;usingH.LabelImg.ShapeBox.Shapes.Base;usingH.LabelImg.ShapeBox.State;usingH.LabelImg.ShapeBox.State.Adds.Base;usingH.LabelImg.ShapeBox.State.Base;usingH.Mvvm.Commands;usingH.Mvvm.ViewModels.Base;usingSystem.Linq;namespaceH.App.LabelImg;publicclassImagePresenter:ModelBindable<ImageBindable>,IShapes{publicImagePresenter(ImageBindablet):base(t){this.RefreshViewStates();}privateObservableCollection<IViewState>_ViewStates=newObservableCollection<IViewState>();[JsonIgnore]publicObservableCollection<IViewState>ViewStates{get{return_ViewStates;}set{_ViewStates=value;RaisePropertyChanged();}}privateIViewState_viewState;[JsonIgnore]publicIViewStateViewState{get{return_viewState;}set{_viewState=value;RaisePropertyChanged();}}IReadOnlyCollection<IShape>IShapes.Shapes{get=>this.Model.Shapes;}protectedvirtualIEnumerable<IViewState>CreateViewStates(){if(IocProject.Instance.CurrentisFileProjectItemprojectItem){foreach(variteminprojectItem.Labels){varb=newSolidColorBrush(item.LabelColor);b.Freeze();yieldreturnnewAddLabelShapesState(this,()=>this.Model.CreateShape(x=>{x.Title=item.LabelName;x.Stroke=b;}));}}}publicvoidRefreshViewStates(){this.ViewStates=this.CreateViewStates().ToObservable();this.ViewState=this.ViewStates.FirstOrDefault();}publicvoidAddShapes(paramsIShape[]shapes){this.Model.AddShapes(shapes.OfType<LabelRectShape>().ToArray());}publicvoidDeleteShapes(paramsIShape[]shapes){this.Model.DeleteShapes(shapes);}publicRelayCommandAddLabelCommand=>newRelayCommand(asyncx=>{LabelItemlabelItem=newLabelItem();varr=awaitIocMessage.Form.ShowEdit(labelItem,x=>x.Title="新增标签");if(r!=true)return;if(IocProject.Instance.CurrentisFileProjectItemprojectItem){projectItem.Labels.Add(labelItem);projectItem.Save(outstringmessage);projectItem.RefreshLabelFilters();this.RefreshViewStates();}});publicRelayCommandShowLabelManagerCommand=>newRelayCommand(asyncx=>{LabelManagerPresenterpresenter=newLabelManagerPresenter();varr=awaitIocMessage.Dialog.Show(presenter);if(r!=true)return;if(IocProject.Instance.CurrentisFileProjectItemprojectItem){projectItem.Labels=presenter.Collection;projectItem.Save(outstringmessage);projectItem.RefreshLabelFilters();this.RefreshViewStates();}});publicRelayCommandClearCommand=>newRelayCommand(x=>{this.Model.Clear();});}publicclassImageThumbPresenter:ModelBindable<ImageBindable>{publicImageThumbPresenter(ImageBindablet):base(t){}}五、注意事项
命名空间匹配
确保ImagePresenter.xaml.cs中的命名空间与ImagePresenter.xaml中的xmlns:local匹配:
<!-- ImagePresenter.xaml -->xmlns:local="clr-namespace:H.App.LabelImg"// ImagePresenter.xaml.csnamespaceH.App.LabelImg;继承类正确
确保ImagePresenter继承自正确的基类:
publicclassImagePresenter:ModelBindable<ImageBindable>,IShapesusing 指令
确保添加必要的 using 指令:
H.Mvvm.ViewModels.Base(ModelBindable)H.Mvvm.Commands(RelayCommand)H.LabelImg.*(ShapeBox 相关)
