使用MVVM框架内的Button动态添加TextBox

我一直爬上陡峭的WPF山! 所以我想创建一个允许用户动态添加文本框的UI。 要做到这一点,他们会点击一个按钮。

我已经设法使用后面的代码创建它,但我想转向MVVM结构,所以我在视图中没有任何代码。 我已经尝试过ICommand和ObservableCollection,但我遗漏了一些东西而且我不知道在哪里。 这是我的简单例子。

XAML:非常基本,只有一个按钮可以添加一行。

          

C#代码背后

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace WPFpractice072514 { ///  /// Interaction logic for MainWindow.xaml ///  public partial class MainWindow : Window { #region members int count = 0; #endregion public MainWindow() { InitializeComponent(); } private void ButtonAddTexboxBlockExecute(Object Sender, RoutedEventArgs e) { TextBox t = new TextBox(); t.Height = 20; t.Width = 20; t.Name = "button"; RowDefinition rowDef1; rowDef1 = new RowDefinition(); mymy.RowDefinitions.Add(rowDef1); ColumnDefinition colDef1; colDef1 = new ColumnDefinition(); mymy.ColumnDefinitions.Add(colDef1); ++count; mymy.Children.Add(t); Grid.SetColumn(t, 1); Grid.SetRow(t, count); } } } 

问题:我需要什么代码(XAML和C#)才能将方法移出后面的代码并进入viewmodel?

您可以使用命令动态添加文本框吗?

我假设文本框必须保存在一个容器中,在这种情况下,它是用于网格的容器。 但是,如果我使用的是MVVM,我是否需要在listview或其他使用ItemsSource的容器中包含文本框?

请按照以下步骤操作:

  1. 使用ItemsControl并将其ItemsSource绑定到ViewModel中的某个集合(最好是ObservableCollection)。
  2. 使用TextBox为ItemsControl定义ItemTemplate
  3. 在ViewModel中创建ICommand并将其绑定到按钮。
  4. 在命令执行集合中添加项目,您将看到自动添加TextBox。

XAML

           

ViewModel

 public class MainWindowViewModel : INotifyPropertyChanged { public ObservableCollection SomeCollection { get; set; } public ICommand TestCommand { get; private set; } public MainWindowViewModel() { SomeCollection = new ObservableCollection(); TestCommand = new RelayCommand(CommandMethod); } private void CommandMethod(object parameter) { SomeCollection.Add("Some dummy string"); } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } } 

RelayCommand

 public class RelayCommand : ICommand { readonly Action _execute = null; readonly Predicate _canExecute = null; public RelayCommand(Action execute) : this(execute, null) { } public RelayCommand(Action execute, Predicate canExecute) { if (execute == null) throw new ArgumentNullException("execute"); _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) { return _canExecute == null ? true : _canExecute((T)parameter); } public event EventHandler CanExecuteChanged { add { CommandManager.RequerySuggested += value; } remove { CommandManager.RequerySuggested -= value; } } public void Execute(object parameter) { _execute((T)parameter); } } 

注意 – 我假设您知道如何通过设置DataContext来使用ViewModel插入View以使绑定魔法工作。

 [link][1] class TestViewModel : BindableBase { private TestModel testModel; public ICommand AddCommand { get; private set; } public TestViewModel(StackPanel stkpnlDynamicControls) { testModel = new TestModel(); TestModel.stkPanel = stkpnlDynamicControls; AddCommand = new DelegateCommand(AddMethod); } public TestModel TestModel { get { return testModel; } set { SetProperty(ref testModel, value); } } private void AddMethod() { Label lblDynamic = new Label() { Content = "This is Dynamic Label" }; TestModel.stkPanel.Children.Add(lblDynamic); } }