【发布时间】:2020-01-09 21:33:01
【问题描述】:
我在设计 WPF 应用程序时正在学习 MVVM 模式。到目前为止,我正在阅读一个非常好的教程,但是它们的模型数据正在我的 ViewModel 的构造函数中填充。在本教程中提到,在现实世界中,数据将由数据库或 XML 文件提供。我真的很想知道如何使用 XML 文件来填充模型数据,因为我讨厌在我的代码中包含硬编码值。
这是我的模型
namespace MVVM_Basics.Models
{
using System;
using System.ComponentModel;
//need to implement the interface INotifyPropertyChange, because this is how WPF does it's data binding.
public class Customer : INotifyPropertyChanged
{
/// <summary>
/// Initializing a new instance of the Customer class
/// </summary>
//this is a default constructor for the Customer class
public Customer(String customerName)
{
Name = customerName;
}
private string _Name;
/// <summary>
/// Gets or Sets the Customers Name
/// </summary>
public String Name
{
get{ return _Name;}
set
{
_Name = value;
OnPropertyChanged("Name");
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
这是视图模型
using MVVM_Basics.Commands;
using MVVM_Basics.Models;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
namespace MVVM_Basics.ViewModels
{
internal class CustomerViewModel
{
/// <summary>
/// Initializes a new instance of the CustomerViewModel class
/// </summary>
//creating the constructor for the class
//setting a Name to a Customer instance
//initializing the UpdateCommand with command we created in the CustomerUpdateCOmmand class, the constructor takes in a ViewModel and since we are
//creating it here, we can reference CustomerViewModel by using the 'this' keyword.
public CustomerViewModel()
{
_Customer = new Customer("David"); //this is the hard coded value that I would like to be populated with a XML file
UpdateCommand = new CustomerUpdateCommand(this);
}
/// <summary>
/// Gets or Sets a Boolean value to indicating whether the Customer can be updated
/// </summary>
public bool CanUpdate
{
get
{
if(Customer == null)
{
return false;
}
return !String.IsNullOrWhiteSpace(Customer.Name);
}
}
//without adding logic to CanUpdate, the button that it is binding to will always be disabled because the default value for a boolean is false
//we added logic that only returned false if there was not a name in the text box.
/// <summary>
/// creates an instance of a Customer
/// </summary>
private Customer _Customer;
public Customer Customer
{
get{ return _Customer; }
}
/// <summary>
/// Gets the UpdateCommand for the ViewModel
/// </summary>
public ICommand UpdateCommand
{
get;
private set;
}
/// <summary>
/// Saves changes made to the Customer instance
/// </summary>
public void SaveChanges()
{
//because this is just a simple demo I am using the Debug property to display dialog. Normally this would save back to your actual dataset
Debug.Assert(false, String.Format("{0} was updated.", Customer.Name));
}
}
}
这里是视图
<Window x:Class="MVVM_Basics.Views.CustomerView"
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:MVVM_Basics.Views"
mc:Ignorable="d"
Title="Customer Update" Height="350" Width="520">
<Grid VerticalAlignment="Top" Margin="15">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Customer Name" />
<TextBox Grid.Column="1" Text="{Binding Customer.Name, UpdateSourceTrigger=PropertyChanged}" />
<Button Grid.Column="2" Command="{Binding UpdateCommand}" Content="Update" />
</Grid>
</Window>
任何帮助将不胜感激,谢谢
【问题讨论】:
-
可能是
XmlDataProvider?更多信息:stackoverflow.com/questions/1866942/… -
这能回答你的问题吗? How to Deserialize XML document
-
这似乎是两个问题合二为一:1)如何将模型传递到 ViewModel,2)如何从 XML 填充模型(这实际上是“如何读取 XML”,是吗?) .