Добавьте пользовательский элемент управления в стековую панель, используя Viewmodel WPF - PullRequest
0 голосов
/ 10 января 2012

У меня есть customcontrol, его нужно добавлять столько раз при нажатии на кнопку.Это должно быть достигнуто из шаблона MVFM 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>

Ответы [ 2 ]

6 голосов
/ 10 января 2012

Я бы сделал это следующим образом:

имеет ObservableCollection<CustomClass> в вашей ViewModel.Представление вашего CustomClass представляет собой шаблон данных с разметкой выше.

Вот полный рабочий пример:

  <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; }
  }
4 голосов
/ 10 января 2012

Чтобы использовать шаблон MVVM, вам понадобится ViewModel, у которого есть список объектов данных, которые привязаны к вашим пользовательским элементам управления. Эти элементы управления могут быть созданы с помощью ItemsControl. Поскольку я не знаю ваших данных, я могу привести вам общий пример.

MainWindow.xaml (Просмотреть)

<ItemsControl ItemsSource="{Binding DataList}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <!-- instead of the TextBlock you would use your control -->
            <TextBlock Text="{Binding}" />
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

MainWindow.xaml.cs (Просмотреть код позади)

public MainWindow()
{
    DataContext = new MainWindowViewModel();
    InitializeComponent();
}

MainWindowViewModel.cs (ViewModel)

public class MainWindowViewModel
{
    public ObservableCollection<string> DataList { get; set; }

    public MainWindowViewModel()
    {
        DataList = new ObservableCollection<string>
                    {
                        "Data 1",
                        "Data 2",
                        "Data 3"
                    };
    }
}

Свойство Binding for Text не имеет пути, поскольку DataContext здесь является строковым объектом DataList. Если вы используете сложные объекты, вы должны использовать Путь к свойству объекта (например, Text={Binding Path=myProperty})

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...