我正在创建一个简单的MVVM应用程序,以及它的功能,
1)在阅读json文件后,在数据网格中显示详细信息。
2)将新记录添加到集合中并保存json文件。
我的问题是在MainWindow中按下Add按钮我打开一个AddContacts窗口,其中有一个Add按钮。现在,当在AddContacts窗口中按下Add按钮时,如何获取Contacts对象数据,以便我可以添加到ContactListViewModel中的ContactsList。 AddContact Window和MainWindow数据上下文都是ContactListViewModel。 通常我会在ContactListViewModel的AddWindow中为add按钮添加另一个Command。但请帮我填充模型数据。
所以我创建了一个模型如下;
public class Contacts:INotifyPropertyChanged
{
private string _firstName;
public string FirstName
{
get { return _firstName; }
set
{
_firstName = value;
NotifyPropertyChanged("FirstName");
}
}
private string _lastName;
public string LastName
{
get { return _lastName; }
set
{
_lastName = value;
NotifyPropertyChanged("LastName");
}
}
private string _dateOfBirth;
public string DateOfBirth
{
get { return _dateOfBirth; }
set
{
_dateOfBirth = value;
NotifyPropertyChanged("DateOfBirth");
}
}
private string _weight;
public string Weight
{
get { return _weight; }
set
{
_weight = value;
NotifyPropertyChanged("Weight");
}
}
private string _height;
public string Height
{
get { return _height; }
set
{
_height = value;
NotifyPropertyChanged("Height");
}
}
private string _phone;
public string Phone
{
get { return _phone; }
set
{
_phone = value;
NotifyPropertyChanged("Phone");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
现在我的视图模型如下;
public class ContactListViewModel
{
private ObservableCollection<Contacts> _contactsCollection;
public ObservableCollection<Contacts> ContactsCollection
{
get { return _contactsCollection; }
set { _contactsCollection = value; }
}
private RelayCommand _addCommand;
public ICommand AddCommand
{
get
{
if (_addCommand == null)
{
_addCommand = new RelayCommand(param => this.OpenAddWindow());
}
return _addCommand;
}
}
private void OpenAddWindow()
{
AddContact contact = new AddContact();
contact.DataContext = this;
contact.ShowDialog();
}
public ContactListViewModel()
{
//As discussed below using a thread.
Thread th = new Thread(new ThreadStart(CreateSampleContacts));
th.Start();
}
//Im hardcoding some contacts but I want to remove the hardcoding and
//add data thats coming from AddWindow
public void CreateSampleContacts()
{
List<Contacts> contactsList = new List<Contacts>();
contactsList.Add(new Contacts
{
FirstName = "Nikhil",
LastName = "ANS",
DateOfBirth = "07/12/1989",
Weight = "184 lbs",
Height = "6.0 feet",
Phone = "805-251-1015"
});
contactsList.Add(new Contacts
{
FirstName = "Sam",
LastName = "B",
DateOfBirth = "04/10/1991",
Weight = "174 lbs",
Height = "5.10 feet",
Phone = "800-800-8000"
});
contactsList.Add(new Contacts
{
FirstName = "Henry",
LastName = "K",
DateOfBirth = "05/06/1988",
Weight = "184 lbs",
Height = "6.4 feet",
Phone = "408-408-4088"
});
if (contactsList.Count > 0)
{
try
{
CreateJsonandWrite(contactsList);
}
catch(Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
}
public async void CreateJsonandWrite(List<Contacts> allContacts)
{
string json = JsonConvert.SerializeObject(allContacts);
await WriteToFile(json);
}
public Task WriteToFile(string json)
{
string path = "~/Contacts.json";
return WriteTextToFileAsync(path, json);
}
//Asynchronosly writing data to the file
public async Task WriteTextToFileAsync(string filePath, string text)
{
byte[] encodedText = Encoding.Unicode.GetBytes(text);
using (FileStream sourceStream = new FileStream(filePath,
FileMode.Append, FileAccess.Write, FileShare.None,
bufferSize: 4096, useAsync: true))
{
await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
};
}
}
主窗口
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0">
<Button Height="25" Width="80">Add</Button>
<Button Height="25" Width="80">Delete</Button>
</StackPanel>
<DataGrid Grid.Row="1" AutoGenerateColumns="False" ItemsSource="{Binding ContactsCollection}">
<DataGrid.Columns>
<DataGridTextColumn Header="First Name" Binding="{Binding FirstName}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding LastName}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding DateOfBirth}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding Weight}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding Height}"/>
<DataGridTextColumn Header="Last Name" Binding="{Binding Phone}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
AddWindow
<Grid HorizontalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<TextBlock>First Name : </TextBlock>
<TextBox Margin="20,0,0,0" Height="25" Width="120" Text="{Binding FirstName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<TextBlock>Last Name :</TextBlock>
<TextBox Margin="20,0,0,0" Height="25" Width="120" Text="{Binding LastName,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="2">
<TextBlock>Date of Birth :</TextBlock>
<DatePickerTextBox Height="25" Width="120" Margin="10,0,0,0" Text="{Binding DateOfBirth,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,StringFormat='dd/mm/yyyy'}">
</DatePickerTextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="3">
<TextBlock>Width :</TextBlock>
<TextBox Margin="45,0,0,0" Height="25" Width="120" Text="{Binding Weight,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="4">
<TextBlock>Height :</TextBlock>
<TextBox Margin="42,0,0,0" Height="25" Width="120" Text="{Binding Height,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="5">
<TextBlock>Phone :</TextBlock>
<TextBox Margin="44,0,0,0" Height="25" Width="120" Text="{Binding Phone,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>
</StackPanel>
<Button Grid.Row="6" Margin="45">Add</Button>
//按下此添加按钮后,我想获取ContactList对象中的// ContactListViewModel中的数据。
答案 0 :(得分:0)
要将数据从子窗口传递到父窗口,您需要按照步骤
进行操作在ParentWindow中将openAddWindow方法修改为
private void OpenAddWindow()
{
AddContact contact = new AddContact();
contact.DataContext = this;
if(contact.ShowDialog() == true)
{
//here i have just given messagebox here you can fetch the data membersof AddContact window
MessageBox.Show(contact.VariableAssumed);
//On add button click in childwindow You can save your new contact in Contacts object(newContact)
//and you can retrieve the newContact here and add it to your Contact list present in parentwindow as below
contactList.Add(contact.newContact);
}
}
答案 1 :(得分:0)
我正在尝试制作您发布的类的示例。希望这有帮助
AddContact类
class AddContact
{
....
public Contacts newContact{get;set;}
public AddContact()
{
newContact = new Contacts();
}
private void OnAddButtonClicked()
{
newContact.FirstName = "Abc";//just i am taking abc asexample you fetch data from the textbox controls
newContact.LastName = "Abc";
.....
//fill all the data members
DialogResult = true;
this.close();
}
}
ContactListViewModel类
class ContactListViewModel
{
.....
private ObservableCollection<Contacts> _contactsCollection;
private void OpenAddWindow()
{
AddContact contact = new AddContact();
contact.DataContext = this;
if(contact.ShowDialog() == true)
{
_contactsCollection.Add(contact.newContact);
}
}
}
答案 2 :(得分:0)
我很惊讶正确答案没有出现在这里。
我会试着解释你如何继续。
首先,您需要在应用程序的运行时间内使用能够包含所有引用的ViewModel的内容。
下载并安装MVVM Toolkit软件包nuget。
之后,尝试使用ViewModelLocator:
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
SimpleIoc.Default.Register<ContactListViewModel>();
SimpleIoc.Default.Register<MainViewModel>();
}
public static ContactListViewModel ContactListVM
{
get
{
return ServiceLocator.Current.GetInstance<ContactListViewModel>();
}
}
public static void CleanContactList()
{
SimpleIoc.Default.Unregister<ContactListViewModel>();
SimpleIoc.Default.Register<ContactListViewModel>();
}
public static MainViewModel MainVM
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
}
public static void CleanMain()
{
SimpleIoc.Default.Unregister<MainViewModel>();
SimpleIoc.Default.Register<MainViewModel>();
}
public static void Cleanup()
{
CleanMain();
CleanContactList();
}
}
以下是a link,可让您正确设置ViewModelLocator。
之后,无论您在代码中的任何位置,都可以通过 ViewModelLocator 中的静态属性调用任何ViewModel,并将任何属性设置到其中。