在 VS2022 中创建 Presenter 文件对

📅 2026/7/6 15:59:24 👁️ 阅读次数 📝 编程学习
在 VS2022 中创建 Presenter 文件对

在 VS2022 中创建 Presenter 文件对

一、ImagePresenter 的本质

ImagePresenter.xaml实际上是一个ResourceDictionary(资源字典),用于定义 DataTemplate,而不是标准的 UserControl 或 Window。

ImagePresenter.xaml → ResourceDictionary(定义 DataTemplate) ImagePresenter.xaml.cs → 对应的代码后台类(定义 ImagePresenter 类)

二、创建方法

方法一:创建 ResourceDictionary + Class(推荐)

步骤 1:创建 XAML 文件

  1. 在 VS2022 中右键点击Presenter文件夹
  2. 选择添加 → 新建项
  3. 搜索 “Resource Dictionary”
  4. 命名为ImagePresenter.xaml
  5. 点击添加

步骤 2:创建对应的 CS 文件

  1. 右键点击Presenter文件夹
  2. 选择添加 → 新建项
  3. 搜索 “Class”
  4. 命名为ImagePresenter.xaml.cs
  5. 点击添加

方法二:手动创建(最简单)

直接在同一目录下创建两个文件:

Presenter/ ├── ImagePresenter.xaml ← ResourceDictionary └── ImagePresenter.xaml.cs ← Class

ImagePresenter.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),可以:

  1. 复制LabelManagerPresenter.xaml→ 重命名为ImagePresenter.xaml
  2. 复制LabelManagerPresenter.xaml.cs→ 重命名为ImagePresenter.xaml.cs
  3. 修改文件内容

四、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>,IShapes

using 指令

确保添加必要的 using 指令:

  • H.Mvvm.ViewModels.Base(ModelBindable)
  • H.Mvvm.Commands(RelayCommand)
  • H.LabelImg.*(ShapeBox 相关)