簡體   English   中英

將多個視圖綁定到同一數據上下文(WPF-MVVM)

[英]Bind multiple views to the same data context (WPF-MVVM)

我的問題可能很愚蠢,但我對WPF和MVVM都很陌生。

那么我們來看下面的例子:

我有一個聯系人應用程序,它使用MainWindow-View中的ObservableCollection<Contact>顯示所有聯系人。

當我按下“添加聯系人”按鈕時,將打開一個新視圖,其中包含用於輸入新聯系人和保存按鈕的文本字段。 但是,當我保存條目時,它會保存到新的Collection中,因為我不在同一個數據上下文中(兩者都使用與DataContext相同的ViewModel)。

我的問題是如何與兩個視圖共享ObservableCollection<Contact> ,以便兩個視圖都可以編輯它並使用相同的集合(即在視圖中保存新的聯系人,主視圖中的列表也會更新)?

一些代碼片段:

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);
}

和XAML:

主窗口:

<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>

Grid將從父窗口繼承DataContext 截至目前,您在每個視圖中創建了兩個視圖模型實例。

同樣從AddContact視圖中刪除它:

<Window.DataContext>
    <ViewModels:ContactManager/>
</Window.DataContext>

...並在打開窗口時設置其DataContext

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

有一些方法可以解決這個問題:

簡單的方法

在主窗口中創建AddContact時,按鈕_Click,inyect或分配ViewModel。 例如:

AddContact(this.DataContext);

要么

new AddContact(){DataContext=this.DataContext);

事件方式

在MVVM體系結構中,您可以在ViewModel與事件之間共享信息,請參閱不同ViewModel之間的Sharin變量

Inyect導航數據

通常,用於導航到頁面的方法允許發送數據,例如NavigationService.Navigate

我希望這可以幫到你。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM