wpf - 使用Viewmodel WPF向堆栈面板添加自定义控件

标签 wpf mvvm

我有一个customcontrol,点击按钮时需要添加多次。这必须从MVVM WPF模式中实现。我已经在这里粘贴了我的代码。如果你们能在这方面提供帮助,那将是很棒的。

请帮我

<Window x:Class="DOCS_APP_ELEMENT.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:usercontrol="clr-namespace:DOCS_APP_ELEMENT"
    xmlns:viewModel="clr-namespace:DOCS_APP_ELEMENT.ViewModels"
    Title="MainWindow" Height="350" Width="400">
<Grid Margin="10" Name="myGrid">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
        <RowDefinition Height="Auto"></RowDefinition>
    </Grid.RowDefinitions>
    <Border CornerRadius="5" BorderBrush="SteelBlue" BorderThickness="2" Grid.Row="0">
        <StackPanel Orientation="Vertical">
            <StackPanel Orientation="Horizontal">
                <Label Content="Type:" Margin="20,0,4,0"></Label>
                <ComboBox Name="cmbQuestionType" Width="300" Style="{Binding ComboBoxStyle}" Margin="0,5,0,5" IsEnabled="False">                   </ComboBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="0,5,0,5">
                <Label Content="Question:" Margin="0,0,4,0"></Label>
                <TextBox Name="txtQuestion" Width="300" Height="50" Margin="0,2,0,0" AcceptsReturn="True"></TextBox>
            </StackPanel>
            <StackPanel Orientation="Horizontal" Margin="0,5,0,5" >
                <Label Content="Answer:" Margin="7,0,4,0"></Label>
                <TextBox Name="txtAnswer" Style="{StaticResource TextboxStyle}" Margin="0,2,0,0"></TextBox>
            </StackPanel>
        </StackPanel>
    </Border>
    <Border CornerRadius="5" BorderBrush="SteelBlue" BorderThickness="2" Grid.Row="1" Margin="0,10,0,0" >
        <ScrollViewer VerticalScrollBarVisibility="Auto" Height="100">
        <StackPanel Name="myCustom" Orientation="Vertical" >
                **<!--<ADD CUSTOM CONTROl HERE>-->**
            </StackPanel>
        </ScrollViewer>
    </Border>
    <Border CornerRadius="5" BorderBrush="SteelBlue" BorderThickness="2" Grid.Row="2" Margin="0,10,0,0">
        <Border.DataContext>
            <viewModel:ViewElements/>                    
        </Border.DataContext>
        <Button  Name="btnAdd" Content="Add" DataContext="{Binding }" Command="{Binding Path=AddInstace}"></Button>
    </Border>
</Grid>

最佳答案

我将通过以下方式进行操作:

在ViewModel中有一个ObservableCollection<CustomClass>。 CustomClass的表示形式是带有上面标记的DataTemplate。

这是一个完整的工作示例:

  <Grid>
    <Grid.DataContext>
      <local:MyViewModel></local:MyViewModel>
    </Grid.DataContext>
      <StackPanel>
      <ScrollViewer VerticalScrollBarVisibility="Auto" Height="200">
        <ItemsControl ItemsSource="{Binding CustomControls}">
          <ItemsControl.ItemTemplate>
            <DataTemplate>
              <Border Background="Green"> 
                <StackPanel>
                  <TextBlock Text="I am a Custom Control"></TextBlock>
                  <TextBlock Text="{Binding DisplayValue}"></TextBlock>
                </StackPanel>
              </Border>
            </DataTemplate>
          </ItemsControl.ItemTemplate>
          <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
              <StackPanel/>
            </ItemsPanelTemplate>
          </ItemsControl.ItemsPanel>
          </ItemsControl>
      </ScrollViewer>
      <Button Width="200" Height="50" Command="{Binding AddControlCommand}">Add Control</Button>
      <Button Width="200" Height="50" Command="{Binding RemoveControlCommand}">Remove Control</Button>
    </StackPanel>
  </Grid>

ViewModel:
  public abstract class ViewModel : INotifyPropertyChanged
  {
    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
      if (PropertyChanged != null)
      {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
      }
    }
  }

  public class RelayCommand : ICommand
  {
    ... look that up yourself if you don't have a derived command class yet in your project... 
  }

  public class MyViewModel : ViewModel
  {
    public ICommand AddControlCommand
    {
      get
      {
        return new RelayCommand(x=>this.AddControl());
      }
    }

    public ICommand RemoveControlCommand
    {
      get
      {
        return new RelayCommand(x => this.RemoveControl());
      }
    }

    private void AddControl()
    {
      CustomControls.Add(new CustomControl() {DisplayValue = "newControl"});
    }

    private void RemoveControl()
    {
      if (CustomControls.Count > 0)
      {
        CustomControls.Remove(CustomControls.Last());
      }
    }

    private ObservableCollection<CustomControl> _customControls;

    public ObservableCollection<CustomControl> CustomControls
    {
      get
      {
        if (_customControls == null)
        {
        _customControls = new ObservableCollection<CustomControl>()
                 {
                   new CustomControl() {DisplayValue = "Control1"},
                   new CustomControl() {DisplayValue = "Control2"},
                   new CustomControl() {DisplayValue = "Control3"}
                 };
        }
        return _customControls;
      }
    }
  }

  public class CustomControl : ViewModel
  {
    public string DisplayValue { get; set; }
  }

关于wpf - 使用Viewmodel WPF向堆栈面板添加自定义控件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8801398/

相关文章:

WPF 绑定(bind)到集合并使用 MVVM 将新项目添加到集合

WPF MVVM如何在 View 更改后重新居中应用程序窗口?

c# - 样式化 RibbonComboBox 内容

wpf - 使用 ItemTemplate 在 ListBoxItems 构建上添加事件

c# - 如何在 WPF 中使用左右键在 tabitem 之间导航

c# - 列表框仅显示一项

javascript - 是否可以让 knockoutjs 更新 'initialdata' 对象?

c# - 绑定(bind)到子项属性

c# - 如何在 viewmodel 方法中更新 busyIndi​​cator 状态?

c# - WPF MVVM 模型中的按钮命令