当绑定到视图模型中的对象时,WPF绑定不起作用

时间:2019-06-08 20:13:55

标签: c# wpf binding

我正在使用MVVM在WPF中创建联系人列表。当用户添加联系人时,NewContact视图将出现在窗口中。文本框应绑定到NewContactViewModel中名为NewContact的对象。 DataContext设置为AppViewModel,它是中央视图模型,但是AppViewModel中有一个名为“ NewContactVM”的NewContact视图模型。因为我直接绑定到该VM,所以我希望它能正常工作。这是NewContact.xaml:

<Window x:Class="ContactList.Windows.NewContact"
         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:ContactList"
        xmlns:vm="clr-namespace:ContactList.ViewModels"
        xmlns:v="clr-namespace:ContactList.Views"
        mc:Ignorable="d"
        Title="NewContact" Height="450" Width="400">

    <Window.DataContext>
        <local:AppViewModel/>
    </Window.DataContext>
    <Grid>
        <Border Padding="10">
            <StackPanel>

                <!-- Contact Entries-->
                <!-- Contact Name -->
                <TextBlock Text="Contact Name" Margin="5 10" />
                <TextBox Text="{Binding NewContactVM.NewContact.Name,
                    FallbackValue=NULL, Mode=TwoWay}" 
                          Padding="2" Margin="5 0" ></TextBox>
                <!-- Contact Number -->
                <TextBlock Text="Contact Number" Margin="5 10" />
                <TextBox Text="{Binding NewContactVM.NewContact.PhoneNumber, FallbackValue=NULL, Mode=TwoWay}"
                     Padding="2" Margin="5 0"></TextBox>
                <!-- Contact Email -->
                <TextBlock Text="Contact Email" Margin="5 10" />
                <TextBox Text="{Binding NewContactVM.NewContact.Email, FallbackValue=NULL, Mode=TwoWay}" 
                     Padding="2" Margin="5 0"></TextBox>

                <!-- Add Contact Button -->
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Button x:Name="AddContactButton"  Grid.Column="1" Content="Add Contact" 
                            Command="{Binding NewContactVM.SaveContactCommand}" Margin="10"/>
                </Grid>
            </StackPanel>
        </Border>
    </Grid>
</Window>

但是,无论何时添加NewContact,它始终为NULL值。这是NewContactViewModel:

    public class NewContactViewModel : ObservableObject
    {
        public ObservableCollection<Contact> Contacts { get; set; }
        private List<Contact> _contacts;

        private Contact _newContact;
        public Contact NewContact
        {
            get { return _newContact; }
            set { OnPropertyChanged(ref _newContact, value); }
        }

        public ICommand OpenNewContactWindowCommand { get; private set; }
        public ICommand SaveContactCommand { get; private set; }

        private IContactDataService _dataService;


        public NewContactViewModel(IContactDataService dataService)
        {
            _dataService = dataService;
            _contacts = dataService.GetContacts().ToList();
            OpenNewContactWindowCommand = new RelayCommand(showNewContact);
            SaveContactCommand = new RelayCommand(Save);
        }

        private void showNewContact()
        {
            NewContact newContact = new NewContact();
            newContact.Show();
        }

        private void Save()
        {
            Contacts = new ObservableCollection<Contact>(_contacts);
            _dataService.Save(_contacts);
            Contacts.Add(NewContact);
            _contacts.Add(NewContact);

        }
    }

因为该值始终为null,所以绑定一定不会发生,但我不知道为什么,我是MVVM体系结构的新手。 (作为参考,Contact对象只是一个具有公共字符串的自定义对象,该公共字符串用于具有getter和setter的Names。)

1 个答案:

答案 0 :(得分:0)

如果我对您的理解正确,则您的代码如下所示:

  1. 您的主要ViewModel称为AppViewModel
  2. 在AppViewModel中,您有一个NewContactVM,它是一个NewContactViewModel类
  3. 在NewContactVM中,您具有showNewContact方法,可在其中创建新的NewContact窗口。
  4. NewContact窗口的新实例创建一个新的(可能未初始化的)AppViewModel。由于此代码,现在您有了一个全新的第二个AppViewModel。

    <Window.DataContext>
        <local:AppViewModel/>
    </Window.DataContext>
    

修复:

由于所有绑定都引用AppViewModel.NewContactVM,因此您只需更改新窗口的数据上下文即可。

  1. 首先从您的XAML中删除此代码

    <Window.DataContext>
        <local:AppViewModel/>
    </Window.DataContext>
    
  2. 然后更改您的showNewContact方法以正确设置DataContext。

    private void showNewContact()
    {
        NewContact newContact = new NewContact();
        newContact.DataContext = this;
        newContact.Show();
    }
    

更新:

如果您的NewContact属性为null,那是因为未在任何地方对其进行初始化。

尝试更改此内容:

private Contact _newContact;
public Contact NewContact
{
    get { return _newContact; }
    set { OnPropertyChanged(ref _newContact, value); }
}

对此

private Contact _newContact = new Contact();
public Contact NewContact
{
    get { return _newContact; }
    set { _newContact = value; }
}