为了账号安全,请及时绑定邮箱和手机立即绑定

将集合引用从视图传递到虚拟机时跟踪集合引用的最佳方法是什么

将集合引用从视图传递到虚拟机时跟踪集合引用的最佳方法是什么

C#
慕标5832272 2023-07-22 16:38:40
我的应用程序是翻译应用程序。它包含传递给不同视图模型的翻译列表。这些视图模型可能会修改这些列表,包括添加和删除操作。为此,我ObservableCollection在构造函数中将此列表转换为 an ,并且我的列表不再被修改。我知道转换为 anObservableCollection会创建一个新对象,并且引用不再相同。它对于相关视图来说工作得很好,但是一旦我想更改为另一个视图,列表就不会更新。我想知道解决这个问题的最佳方法是什么?我认为我可以创建一个自定义 ObservableCollection,其中包含相应的列表,并在完成添加或删除操作时自动更新它。看起来与此类似的东西。看法public partial class MainWindow : Window{    private void ListViewItem_PreviewMouseDown(objectsender,MouseButtonEventArgs e)    {        // this is where I instanciate the viewModel, and the         // list<Translation> isn't modify once I close the view        DataContext = new ModifyWordVM(translations);    }}视图模型public class ModifyWordVM: INotifyPropertyChanged{    private ObservableCollection<TranslationVM> translations;    public ObservableCollection<TranslationVM> Translations    {        get { return translations; }        set { translations = value; OnPropertyChanged("Translations"); }    }    public ModifyWordVM(List<Translation> translations)    {        // Converting list to ObservableCollection        Translations = ConvertionHelper.ConvertTo(translations);    }}我想知道恢复修改后的列表的更干净的方法是什么。
查看完整描述

1 回答

?
炎炎设计

TA贡献1808条经验 获得超4个赞

您应该封装翻译及其操作。为此,只需引入一个类,例如TranslationService在所有相关视图模型之间共享的类。为了省略臭单例,我将服务的实例添加到App.xaml资源中。


这个想法是翻译列表的所有修改都发生在一个位置或类型中。与视图的绑定源相同的类型。添加新翻译时,视图应调用ICommand视图模型上的 a。该命令将AddTranslation调用TranslationService. 删除也一样。对翻译集合的任何更改现在都将反映在整个应用程序中。


如果您还想捕获实际翻译的修改(例如重命名或编辑),则还TranslationService需要处理项目PropertyChanged的事件。 当项目属性更改时,必须通过引发该属性的事件来响应。这也需要实施这些项目。ObservableCollection

TranslationServicePropertyChangedObservableCollectionTranslationsINotifyPropertyChanged


App.xaml

共享TranslationService实例


<Application.Resources>

    <TranslationService x:Key="TranslationService">

        <TranslationService.DatabaseService>

            <DatabaseService />

        </TranslationService.DatabaseService>

    </TranslationService>

</Application.Resources>

MainWindow.xaml.cs


public partial class MainWindow : Window

{

    private void ListViewItem_PreviewMouseDown(objectsender,MouseButtonEventArgs e)

    {

        // Instantiate the view model and initialize DataContext from XAML instead.

        // This method became redundant.

    }

}

主窗口.xaml


<Window.DataContext>

  <ModifyWordVM>

    <ModifyWordVM.TranslationService>


      <!-- Reference the shared instance -->

      <StaticResource ResourceKey="TranslationService" />

    </ModifyWordVM.TranslationService>

  </ModifyWordVM>

</Window.DataContext>

修改WordVM.cs


public class ModifyWordVM: INotifyPropertyChanged

{    

    public ModifyWordVM()

    {}


    public AddTranslation(Translation translation) => this.translationService.AddTranslation(translation);


    public RemoveTranslation(Translation translation) => this.translationService.RemoveTranslation(translation);


    public TranslationService TranslationService {get; set;}


    public ObservableCollection<TranslationVM> Translations => this.translationService.Translations; 


}

翻译服务.cs


public class TranslationService

{

    public TranslationService()

    {}


    public AddTranslation(Translation translation)

    {

        // Add translations

    }


    public RemoveTranslation(Translation translation)

    {

        // Remove translations

    }


    private DatabaseService databaseService;

    public DatabaseService DatabaseService

    {

        get => this.databaseService; 

        set 

        { 

            this.databaseService = value; 

            this.Translations = databaseService.getTranslations; 

         }

    }


    private ObservableCollection<TranslationVM> translations;

    public ObservableCollection<TranslationVM> Translations

    {

        get => this.translations;

        set 

        { 

            this.translations = value; 

            OnPropertyChanged("Translations"); 

         }

    }

}


查看完整回答
反对 回复 2023-07-22
  • 1 回答
  • 0 关注
  • 106 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信