我有一个网格布局。每行有三列。 1stcolumn包含TextBox,第2列和第3列包含TextBlock。
我添加了一个新按钮,我想要做的是每当用户点击按钮时,它会生成一个新行,其中包含第一列包含的TextBox,第二列和第三列包含TextBlock。
我正在做这个我希望 获取用户在每个文本框中输入的值(名称) ,然后 做一些Web服务被调用以检索相关值 到 显示在两个TextBlocks 上的同一行。
我已经搜索过几个与此相关的stackoverflow线程但主要建议您通过将新控件(例如.textbox)作为子项添加到网格布局而不是使用MVVM来实现事件处理程序buttonClicked()。
我想知道我是否有办法使用MVVM实现这一目标?有什么建议吗?
答案 0 :(得分:1)
仔细阅读上述评论@benPearce指出了对同一问题dynamically add controls的出色回答。希望下面的一些额外信息仍然有用。
要动态添加控件,请使用ItemsControl或衍生物并绑定到您要使用的视图模型的集合。这只是一个真实的基本示例,为了简洁省略了一些样板:
<强> XAML 强>
<Window x:Class="MyWpfApp.MainWindow"
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:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Button Content="Add New Entry" Command="{Binding AddNewEntryCommand}"/>
<ItemsControl Grid.Row="1" ItemsSource="{Binding TextEntryItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Label}"/>
<TextBox Text="{Binding Data}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
<强> C#强>
namespace MyWpfApp {
public class MainWindowViewModel : INotifyPropertyChanged {
private void AddNewEntry() {
TextEntryItems.Add(new TextEntryViewModel("NewItem"));
}
private ObservableCollection<TextEntryViewModel> textEntryItems;
public ObservableCollection<TextEntryViewModel> TextEntryItems { get { return textEntryItems; } set { textEntryItems = value; FirePropertyChanged(); } }
public ICommand AddNewEntryCommand { get { new RelayCommand(AddNewEntry)} }
}
public class TextEntryViewModel : INotifyPropertyChanged {
public TextEntryViewModel(string label) {
Label = label;
}
private string label;
public string Label { get { return label; } set { label = value; FirePropertyChanged(); } }
private string data;
public string Data { get { return data; } set { data = value; FirePropertyChanged(); } }
}
}