WPF和MVVM模式的新世界。我希望有人可以提供一个超级简单的描述,说明如何使用文本框创建和添加新对象到observableColllection来设置属性和按钮触发的命令。
到目前为止我所拥有的:
模型
public class CarModel : NotifyBase
{
#region Private Members
/// <summary>
/// Private members for the class Car
/// </summary>
private string _manufacturer;
private string _model;
private string _year;
private string _color;
private string _regNumber;
private EngineModel _eng;
#endregion
#region Public Properties
/// <summary>
/// Public properties for the class Car (used for view binding)
/// </summary>
public string Manufacturer {
get { return _manufacturer; }
set {
if (_manufacturer != value)
{
_manufacturer = value;
RaisePropertyChanged("Manufacturer");
}
}
}
public string Model {
get { return _model; }
set {
if (_model != value)
{
_model = value;
RaisePropertyChanged("Model");
}
}
}
.
.
.
视图模型
class MainViewModel : NotifyBase
{
#region Private Members
/// <summary>
/// Privtae members for the class MainViewModel
/// </summary>
private ObservableCollection<CarModel> _carRegistry;
private CarModel _selectedCar;
private CarModel _car;
private ICommand _addCarCommand;
#endregion
#region Public Properties
/// <summary>
/// Public members for the class MainModelView (used for view binding)
/// </summary>
public ObservableCollection<CarModel> CarRegistry{
get { return _carRegistry; }
set {
_carRegistry = value;
RaisePropertyChanged("CarRegistry");
}
}
public CarModel SelectedCar
{
get { return _selectedCar; }
set
{
_selectedCar = value;
RaisePropertyChanged("SelectedCar");
}
}
public CarModel Car
{
get { return _car; }
set {
_car = value;
RaisePropertyChanged("Car");
}
}
public ICommand AddCarCommand
{
get {
if (_addCarCommand == null)
{
_addCarCommand = new RelayCommand(param =>new CarModel(), param => true);
}
return _addCarCommand;
}
}
#endregion
#region Constructor
/// <summary>
/// MainViewModel constructor
/// </summary>
public MainViewModel()
{
CarRegistry = new ObservableCollection<CarModel>()
{
//Dummy data
new CarModel(){Manufacturer = "Volvo", Model = "V70", Year = "2000", Color = "White", RegNumber = "CDC-123",
Engine = new EngineModel(){Serial = "END125456#", Volume = "2.0"}},
new CarModel(){Manufacturer = "Volvo", Model = "V40", Year = "2005", Color = "Black", RegNumber = "ITI-456",
Engine = new EngineModel(){Serial = "IND554567#", Volume = "1.6"}},
new CarModel(){Manufacturer = "Ford", Model = "Escort", Year = "1995", Color = "Blue", RegNumber = "GHD-777",
Engine = new EngineModel(){Serial = "GHTSJ5556#", Volume = "2.0"}},
};
}
#endregion
#region Methods
private void AddCar(object o)
{
//add new carModel to _carRegistry
}
#endregion
}
RelayCommand
class RelayCommand:ICommand
{
#region Private Members
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExecute == null || _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
//if(parameter != null)
_canExecute(parameter);
}
}
如果我理解正确,那么我需要将文本框绑定到ViewModel中的属性以及触发AddCarCommand
的按钮,但我不知道应该如何实现它。任何帮助将不胜感激!!!
//森
修改
XAML
目前我的xaml看起来像这样:
<Window x:Class="CarData_Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:CarData_Test"
Title="Car Data Test" Height="606.645" Width="758.759">
<Window.DataContext>
<local:MainViewModel/>
</Window.DataContext>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="1" HorizontalAlignment="Left" Margin="10,10,0,0" TextWrapping="Wrap" Text="CAR INFORMATION" VerticalAlignment="Top" FontWeight="Bold" FontFamily="Segoe WP Light" RenderTransformOrigin="0.497,-1.834" FontSize="16"/>
<TextBlock HorizontalAlignment="Left" Margin="28,10,0,0" TextWrapping="Wrap" Text="CAR REGISTER" VerticalAlignment="Top" FontFamily="Segoe WP Light" FontSize="16"/>
<ListView HorizontalAlignment="Left" Height="446" Margin="28,31,0,0" VerticalAlignment="Top" Width="323" ItemsSource="{Binding CarRegistry}" SelectedItem="{Binding SelectedCar}">
<ListView.View>
<GridView>
<GridViewColumn Width="Auto" Header="Reg Number" DisplayMemberBinding="{Binding RegNumber}"/>
<GridViewColumn Width="Auto" Header="Manufacturer" DisplayMemberBinding="{Binding Manufacturer}"/>
<GridViewColumn Width="Auto" Header="Model" DisplayMemberBinding="{Binding Model}"/>
<GridViewColumn Width="Auto" Header="Year" DisplayMemberBinding="{Binding Year}"/>
<GridViewColumn Width="Auto" Header="Color" DisplayMemberBinding="{Binding Color}"/>
</GridView>
</ListView.View>
</ListView>
<StackPanel Grid.Column="1" HorizontalAlignment="Left" Height="446" Margin="10,31,0,0" VerticalAlignment="Top" Width="335">
<TabControl DataContext="{Binding SelectedCar}" Height="446">
<TabItem Header="Overview">
<Grid Background="#FFE5E5E5">
<StackPanel>
<StackPanel Orientation="Horizontal">
<Label Margin="20 30 0 0" Content="Registration Number"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBox Name="txtbox_regNumber" Text="{Binding RegNumber, UpdateSourceTrigger=PropertyChanged}" Width="112" Margin="25 3 0 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Manufacturer" Margin="21 0 0 0"/>
<Label Content="Model" Margin="76 0 0 0"></Label>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBox Name="txtbox_manufacturer" Text="{Binding Manufacturer, UpdateSourceTrigger=PropertyChanged}" Width="112" Margin="25 0 0 0"/>
<TextBox Name="txtbox_model" Text="{Binding Model, UpdateSourceTrigger=PropertyChanged}" Width="112" Margin="44 0 0 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Year" Margin="22 0 0 0"/>
<Label Content="Color" Margin="123 0 0 0"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBox Name="txtbox_year" Text="{Binding Year, UpdateSourceTrigger=PropertyChanged}" Width="112" Margin="25 0 0 0"/>
<TextBox Name="txtbox_color" Text="{Binding Color, UpdateSourceTrigger=PropertyChanged}" Width="112" Margin="44 0 0 0"/>
</StackPanel>
</StackPanel>
<GroupBox Header="Edit" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="182" Width="291"/>
</Grid>
</TabItem>
<TabItem Header="Engine Data">
<Grid Background="#FFE5E5E5">
<StackPanel>
<StackPanel>
<Label Content="Serial Number" Margin="20 30 0 0"/>
</StackPanel>
<StackPanel>
<TextBox HorizontalAlignment="Left" Text="{Binding Engine.Serial, UpdateSourceTrigger=PropertyChanged}" Width="112" Margin="25 3 0 0"/>
</StackPanel>
<StackPanel>
<Label Content="Volume" Margin="20 15 0 0"/>
</StackPanel>
<StackPanel>
<TextBox HorizontalAlignment="Left" Text="{Binding Engine.Volume, UpdateSourceTrigger=PropertyChanged}" Width="112" Margin="25,0,0,0"/>
</StackPanel>
</StackPanel>
<GroupBox Header="Edit" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="182" Width="291"/>
</Grid>
</TabItem>
</TabControl>
</StackPanel>
<Button Command="{Binding AddCarCommand}" Content="Add" Grid.Column="1" HorizontalAlignment="Left" Margin="10,494,0,0" VerticalAlignment="Top" Width="75"/>
</Grid>
理想情况下,我希望能够通过选项卡中的文本框进行添加,但它们当前已绑定到selectedCar。
答案 0 :(得分:1)
您的RelayCommand
应该调用AddCar
方法:
public ICommand AddCarCommand
{
get
{
if (_addCarCommand == null)
{
_addCarCommand = new RelayCommand(param => AddCar(param), param => true);
}
return _addCarCommand;
}
}
在此方法中,将新的Car
对象添加到源集合中:
private void AddCar(object o)
{
CarRegistry.Add(new CarModel { Model = Car.Model });
}
在视图中,您可以将TextBoxes
绑定到Car对象的属性:
<TextBox Text="{Binding Car.Model, UpdateSourceTrigger=PropertyChanged}" />
...和Button
到命令属性:
<Button Command="{Binding AddCarCommand}" />
不要忘记设置视图的DataContext
:
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
...并在视图模型中实际创建一个Car
对象:
private CarModel _car = new CarModel();
编辑:
命令的Execute
方法应调用_execute
操作:
public void Execute(object parameter)
{
_execute(parameter);
}
答案 1 :(得分:0)
在您的视图中基本上是XAML,您需要将命令绑定到按钮。 Button具有命令属性。将命令绑定到它 例如
<Button Command={Binding AddCarCommand} CommandParameter="{Binding SelectedCar}">
对于所有这些工作,您必须将view的DataContext属性设置为MainViewModel