C# 将多个视图绑定到同一数据上下文(WPF-MVVM)

C# 将多个视图绑定到同一数据上下文(WPF-MVVM),c#,wpf,mvvm,C#,Wpf,Mvvm,我的问题可能很愚蠢,但我对WPF和MVVM还是相当陌生的 因此,让我们以以下示例为例: 我有一个通讯录应用程序,它在主窗口视图中使用observedcollection显示所有联系人 当我按下“添加联系人”按钮时,会打开一个新视图,其中有文本字段供用户输入新联系人和保存按钮。但是,当我保存条目时,它会保存到新集合中,因为我不在相同的数据上下文中(两者都使用与DataContext相同的ViewModel) 我的问题是如何与两个视图共享ObservableCollection,以便两个视图都可以编

我的问题可能很愚蠢,但我对WPF和MVVM还是相当陌生的

因此,让我们以以下示例为例:

我有一个通讯录应用程序,它在主窗口视图中使用
observedcollection
显示所有联系人

当我按下“添加联系人”按钮时,会打开一个新视图,其中有文本字段供用户输入新联系人和保存按钮。但是,当我保存条目时,它会保存到新集合中,因为我不在相同的数据上下文中(两者都使用与DataContext相同的ViewModel)

我的问题是如何与两个视图共享
ObservableCollection
,以便两个视图都可以编辑它并使用相同的集合(即在视图中保存新联系人,并且主视图中的列表也会得到更新)

一些代码片段:

private Contact contact;
private ObservableCollection<Contact> _contacts;

public ContactManager()
{
    Contacts = new ObservableCollection<Contact>();
    contact = new Contact();
}

public ObservableCollection<Contact> Contacts
{
    get { return _contacts; }
    set
    {
        _contacts = value;
        RaisePropertyChangedEvent("Contacts");
    }
}

public String Anrede
{
    get { return contact.Anrede; }
    set
    {
        contact.Anrede = value;
        RaisePropertyChangedEvent("Anrede");
    }
}

public String Vorname
{
    get { return contact.Vorname; }
    set
    {
        contact.Vorname = value;
        RaisePropertyChangedEvent("Vorname");
    }
}

public String Nachname
{
    get { return contact.Nachname; }
    set
    {
        contact.Nachname = value;
        RaisePropertyChangedEvent("Nachname");
    }
}

public String Adresse
{
    get { return contact.Adresse; }
    set
    {
        contact.Adresse = value;
        RaisePropertyChangedEvent("Adresse");
    }
}

public String Telefonnummer
{
    get { return contact.Telefonnummer; }
    set
    {
        contact.Telefonnummer = value;
        RaisePropertyChangedEvent("Telefonnummer");
    }
}


public ICommand CreateTestContactCommand
{
    get { return new DelegateCommand(CreateTestContact); }
}

public ICommand AddNewContactCommand
{
    get { return new DelegateCommand(AddNewContact); }
}

private void CreateTestContact()
{
    var testContact = new Contact
    {
        Anrede = "Herr",
        Vorname = "Max",
        Nachname = "Mustermann",
        Adresse = "Mustermannstraße 13",
        Telefonnummer = "123456789"
    };

    Contacts.Add(testContact);
}

private void AddNewContact()
{
    Contacts.Add(contact);
}
私人联系;
私人可观察收集联系人;
公共联络经理()
{
Contacts=新的ObservableCollection();
触点=新触点();
}
公开收集联系人
{
获取{return\u contacts;}
设置
{
_接触=价值;
提高产权变更(“联系人”);
}
}
公共字符串
{
获取{return contact.Anrede;}
设置
{
contact.Anrede=值;
提高产权变更(“Anrede”);
}
}
公共字符串名称
{
获取{return contact.Vorname;}
设置
{
contact.Vorname=value;
RaisePropertyChangedEvent(“Vorname”);
}
}
公共字符串Nachname
{
获取{return contact.Nachname;}
设置
{
contact.Nachname=值;
提高产权变更(“Nachname”);
}
}
公共字符串地址
{
获取{return contact.Adresse;}
设置
{
contact.adrese=值;
提高产权变更(“ADRESE”);
}
}
公用字符串电传打字机
{
获取{return contact.telefonnumer;}
设置
{
contact.Telefonnummer=值;
提高产权变更(“电信商”);
}
}
公共ICommand CreateTestContactCommand
{
获取{返回新的DelegateCommand(CreateTestContact);}
}
公共ICommand AddNewContactCommand
{
获取{returnnewdelegatecommand(AddNewContact);}
}
私有void CreateTestContact()
{
var testContact=新联系人
{
Anrede=“Herr”,
Vorname=“Max”,
Nachname=“Mustermann”,
Adresse=“Mustermannstraße 13”,
Telefonnummer=“123456789”
};
Contacts.Add(testContact);
}
私有void AddNewContact()
{
联系人。添加(联系人);
}
以及XAMLs:

主窗口:

<Window
    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:ContactBook_Test"
    xmlns:ViewModels="clr-namespace:ContactBook_Test.ViewModels" x:Class="ContactBook_Test.MainWindow"
    mc:Ignorable="d"
    Title="MainWindow" Height="488" Width="533" ResizeMode="NoResize">
<Window.DataContext>
    <ViewModels:ContactManager/>
</Window.DataContext>
<Grid>
    <Grid.DataContext>
        <ViewModels:ContactManager/>
    </Grid.DataContext>
    <Label Content="Kontaktbuch" HorizontalContentAlignment="Center" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" FontSize="36" FontFamily="Calibri" Width="498"/>
    <DataGrid ItemsSource="{Binding Contacts}" AutoGenerateColumns="True"  CanUserAddRows="false" HorizontalAlignment="Left" Height="327" Margin="10,69,0,0" VerticalAlignment="Top" Width="498"/>
    <Button Command="{Binding CreateTestContactCommand}" Content="Testkontakt hinzufügen" HorizontalAlignment="Left" Margin="198,415,0,0" VerticalAlignment="Top" Width="128"/>
    <Button Content="Neuer Kontakt" HorizontalAlignment="Left" Margin="16,31,0,0" VerticalAlignment="Top" Width="87" Click="Button_Click"/>

</Grid>

添加联系人:

<Window
    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:ViewModels="clr-namespace:ContactBook_Test.ViewModels" x:Class="ContactBook_Test.Views.AddContact"
    mc:Ignorable="d"
    Title="AddContact" Height="300" Width="300">
<Window.DataContext>
    <ViewModels:ContactManager/>
</Window.DataContext>
<Grid>
    <Grid.DataContext>
        <ViewModels:ContactManager/>
    </Grid.DataContext>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="84,46,0,0" TextWrapping="Wrap" Text="{Binding Anrede}" VerticalAlignment="Top" Width="200" />
    <TextBox HorizontalAlignment="Left" Height="23" Margin="84,85,0,0" TextWrapping="Wrap" Text="{Binding Vorname}" VerticalAlignment="Top" Width="200"/>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="84,123,0,0" TextWrapping="Wrap" Text="{Binding Nachname}" VerticalAlignment="Top" Width="200"/>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="84,163,0,0" TextWrapping="Wrap" Text="{Binding Adresse}" VerticalAlignment="Top" Width="200"/>
    <TextBox HorizontalAlignment="Left" Height="23" Margin="84,201,0,0" TextWrapping="Wrap" Text="{Binding Telefonnummer}" VerticalAlignment="Top" Width="200"/>
    <Button Command ="{Binding AddNewContactCommand}" Content="Speichern" HorizontalAlignment="Left" Margin="107,240,0,0" VerticalAlignment="Top" Width="75"/>
    <Label Content="Anrede" HorizontalAlignment="Left" Margin="12,43,0,0" VerticalAlignment="Top"/>
    <Label Content="Name" HorizontalAlignment="Left" Margin="12,82,0,0" VerticalAlignment="Top"/>
    <Label Content="Nachname" HorizontalAlignment="Left" Margin="12,120,0,0" VerticalAlignment="Top"/>
    <Label Content="Adresse" HorizontalAlignment="Left" Margin="12,159,0,0" VerticalAlignment="Top"/>
    <Label Content="Telefon" HorizontalAlignment="Left" Margin="12,198,0,0" VerticalAlignment="Top"/>

</Grid>


两个视图应使用相同的视图模型实例。从两个视图中删除此选项:

<Grid.DataContext>
    <ViewModels:ContactManager/>
</Grid.DataContext>
…并在打开窗口时设置其
DataContext

AddContact addContact = new AddContact();
addContact.DataContext = this.DataContext;
addContact.Show():

有一些方法可以解决此问题:

捷径 在主窗口按钮中创建AddContact时,请单击、输入或指定ViewModel。例如:

AddContact(this.DataContext);

事件方式 在MVVM体系结构中,您可以通过事件在ViewModels之间共享信息,请参阅

关于导航的输入数据 通常,用于导航到页面的方法允许发送数据, 比如说


我希望这能对您有所帮助。

也许可以发布一些代码来帮助我们帮助您。但是,如果已将两个视图的datacontext设置为相同的视图模型,则只需将ICommand添加到“添加联系人”按钮,并在该命令中将新条目添加到ObservableCollection@DanieleSartori使用代码更新问题通常在创建新的
窗口时使用
var newWnd=new AddContact();newWnd.DataContext=this.DataContext
AddContact(this.DataContext);
new AddContact(){DataContext=this.DataContext);