Dynamically Adding TextBox using a Button within MVVM framework

前端 未结 2 600
南笙
南笙 2020-12-14 12:25

I keep climbing the steep WPF hill! So I want to create a UI that allows the user to dynamically add a text box. To do this they would hit a button.

I\'ve managed

相关标签:
2条回答
  • 2020-12-14 12:57

    Follow these steps and you are done:

    1. Use ItemsControl and bind it's ItemsSource to some collection (preferably ObservableCollection) in your ViewModel.
    2. Define ItemTemplate for ItemsControl with TextBox in it.
    3. Create an ICommand in ViewModel and bind it to button.
    4. On command execute add item in the collection and you will see TextBox gets added automatically.

    XAML:

    <StackPanel>
        <Button Content="Add TextBox" Command="{Binding TestCommand}"/>
        <ItemsControl ItemsSource="{Binding SomeCollection}">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Path=.}"/>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
    

    ViewModel:

    public class MainWindowViewModel : INotifyPropertyChanged
    {
        public ObservableCollection<string> SomeCollection { get; set; }
        public ICommand TestCommand { get; private set; }
    
        public MainWindowViewModel()
        {
            SomeCollection = new ObservableCollection<string>();
            TestCommand = new RelayCommand<object>(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<T> : ICommand
    {    
        readonly Action<T> _execute = null;
        readonly Predicate<T> _canExecute = null;
    
        public RelayCommand(Action<T> execute)
            : this(execute, null)
        {
        }    
    
        public RelayCommand(Action<T> execute, Predicate<T> 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);
        }
    }
    

    Note - I assume you know how to plug View with your ViewModel by setting DataContext to make the binding magic to work.

    0 讨论(0)
  • 2020-12-14 13:03
    [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);  
            }  
        }
    
    0 讨论(0)
提交回复
热议问题