Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在将集合引用从视图传递到VM时,跟踪它们的最佳方法是什么_C#_Wpf - Fatal编程技术网

C# 在将集合引用从视图传递到VM时,跟踪它们的最佳方法是什么

C# 在将集合引用从视图传递到VM时,跟踪它们的最佳方法是什么,c#,wpf,C#,Wpf,我的应用程序是一个翻译应用程序。它包含传递给不同viewmodel的转换列表。这些视图模型可以修改这些列表,包括添加和删除操作。为此,我将此列表转换为构造函数中的ObservableCollection,并且不再修改我的列表。我知道,转换为一个可观测集合会创建一个新对象,并且引用不再相同。它对相关视图非常有效,但是一旦我想更改到另一个视图,列表就不会更新。我想知道解决这个问题的最好方法是什么 我想我可以创建一个自定义的ObservableCollection,它将包含相应的列表,并在执行添加或删

我的应用程序是一个翻译应用程序。它包含传递给不同viewmodel的转换列表。这些视图模型可以修改这些列表,包括添加和删除操作。为此,我将此列表转换为构造函数中的
ObservableCollection
,并且不再修改我的列表。我知道,转换为一个
可观测集合
会创建一个新对象,并且引用不再相同。它对相关视图非常有效,但是一旦我想更改到另一个视图,列表就不会更新。我想知道解决这个问题的最好方法是什么

我想我可以创建一个自定义的ObservableCollection,它将包含相应的列表,并在执行添加或删除操作时自动更新它。看起来很像的东西

看法

公共部分类主窗口:窗口
{
私有无效列表视图项_预览鼠标向下(objectsender,鼠标按钮Ventargs e)
{
//这是我实例化viewModel和
//一旦我关闭视图,列表就不会被修改
DataContext=新的ModifyWordVM(翻译);
}
}
视图模型

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);
    }
}
公共类ModifyWordVM:INotifyPropertyChanged
{
私人收藏翻译;
公开收集翻译
{
获取{返回翻译;}
设置{translations=value;OnPropertyChanged(“translations”);}
}
公共ModifyWordVM(列表翻译)
{
//将列表转换为ObservableCollection
Translations=ConvertionHelper.ConvertTo(翻译);
}
}

我想知道返回修改后的列表的更干净的方法是什么。

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

其思想是翻译列表的所有修改都在一个位置或类型中进行。与视图的绑定源的类型相同。添加新翻译时,视图应调用视图模型上的
ICommand
。此命令将调用
TranslationService
上的
AddTranslation
方法。移除时相同。对翻译集合的任何更改现在都将反映在整个应用程序中

如果您还希望捕获对实际翻译的修改(例如重命名或编辑),
TranslationService
还需要处理
observedcollection
项的
PropertyChanged
事件。
当items属性发生更改时,
TranslationService
必须通过引发
ObservableCollection
属性
Translations
PropertyChanged
事件进行响应。这将要求项目也实现
INotifyPropertyChanged

App.xaml
共享
TranslationService
实例

<Application.Resources>
    <TranslationService x:Key="TranslationService">
        <TranslationService.DatabaseService>
            <DatabaseService />
        </TranslationService.DatabaseService>
    </TranslationService>
</Application.Resources>
main window.xaml

<Window.DataContext>
  <ModifyWordVM>
    <ModifyWordVM.TranslationService>

      <!-- Reference the shared instance -->
      <StaticResource ResourceKey="TranslationService" />
    </ModifyWordVM.TranslationService>
  </ModifyWordVM>
</Window.DataContext>

修改wordvm.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.
    }
}
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; 

}
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"); 
         }
    }
}
公共类ModifyWordVM:INotifyPropertyChanged
{    
公共ModifyWordVM()
{}
public AddTranslation(Translation Translation)=>this.translationService.AddTranslation(Translation);
公共RemoveTranslation(Translation Translation)=>this.translationService.RemoveTranslation(Translation);
公共翻译服务翻译服务{get;set;}
public ObservableCollection Translations=>this.translationService.Translations;
}
TranslationService.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.
    }
}
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; 

}
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"); 
         }
    }
}
公共类翻译服务
{
公共翻译服务()
{}
公共翻译(翻译)
{
//添加翻译
}
公共移除翻译(翻译)
{
//删除翻译
}
专用数据库服务数据库服务;
公共数据库服务数据库服务
{
get=>this.databaseService;
设置
{ 
this.databaseService=值;
this.Translations=databaseService.getTranslations;
}
}
私人收藏翻译;
公开收集翻译
{
get=>this.translations;
设置
{ 
这就是价值;
OnPropertyChanged(“翻译”);
}
}
}

谢谢,它现在工作得很好。唯一的问题是我没有完全理解App.xaml中发生了什么。它是否创建了我的服务的实例?是的,它创建了
TranslationService
的共享实例。您可以从代码中的任何地方绑定到此实例,因为它是全局的。现在每个类都可以使用相同的
TranslaionService
,谢谢您的综合回复