本文介绍了使用 Viewmodel WPF 将自定义控件添加到堆栈面板的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个自定义控件,需要在单击按钮时多次添加.这必须从 MVVM WPF 模式中实现.我已经在这里粘贴了我的代码.如果你们能在这方面提供帮助,那就太好了.

I have a customcontrol, need to be added as many times when clicing on a button. This has to achived from MVVM WPF pattern. i have pasted my code here. It will be great if you guys can help on this.

请帮帮我

<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 的表示是带有上述标记的 DataTemplate.

have a ObservableCollection<CustomClass> in your ViewModel. The representation of your CustomClass is a DataTemplate with your above Markup.

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

Here's a full working example:

  <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>

视图模型:

  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; }
  }

这篇关于使用 Viewmodel WPF 将自定义控件添加到堆栈面板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 13:58