Динамически добавлять и удалять стековую панель - PullRequest
1 голос
/ 26 апреля 2011

enter image description here

У меня есть один WrapPanel (с зеленым фоном) внутри ListBox (с серым фоном).

Я пытаюсь динамически добавить StackPanel несколько раз (нажав на кнопку под данным изображением) в WrapPanel.

StackPanel содержит Button с содержимым «X». Я хочу удалить отдельные StackPanel объекты (с оранжевым фоном) при нажатии этой кнопки.

Как это можно решить?

Ответы [ 2 ]

6 голосов
/ 26 апреля 2011

Привязка данных & Шаблонирование данных + Командование

Ваш вопрос довольно обширный. Основная схема заключается в создании привязываемых коллекций, создании шаблонов их данных и удалении из них выбранного элемента с помощью команды или события.

Пример DataTemplating с использованием ItemsControl, который внутренне использует WrapPanel для макета:

<ItemsControl ItemsSource="{Binding DpData}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <WrapPanel />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Grid>
                <!-- The content goes here, X-Button will be overlayed -->
                <Button HorizontalAlignment="Right"
                        VerticalAlignment="Top"
                        Content="X" Click="RemoveItem_Click"/>
            </Grid>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>
// Does not need to be a dependency property.
public static readonly DependencyProperty DpDataProperty =
    DependencyProperty.Register("DpData", typeof(ObservableCollection<Employee>), typeof(MainWindow), new UIPropertyMetadata(new ObservableCollection<Employee>()));
public ObservableCollection<Employee> DpData
{
    get { return (ObservableCollection<Employee>)GetValue(DpDataProperty); }
    set { SetValue(DpDataProperty, value); }
}
// For simplicity i use an event instead of a command.
private void RemoveItem_Click(object sender, RoutedEventArgs e)
{
    var button = (FrameworkElement)sender;
    var emp = (Employee)button.DataContext;
    DpData.Remove(emp);
}

Если вы делаете это таким образом, вы, конечно, не должны добавлять панель при нажатии кнопки добавления, а просто элемент данных в коллекцию. Панель будет сгенерирована автоматически.

0 голосов
/ 27 апреля 2011

Это окончательный код ..........

MainWindow.xaml

<Window.Resources>
    <DataTemplate x:Key="itemsTemplate">
        <!-- This might also be included in a UserControl -->
        <Border Width="200" Height="200" CornerRadius="10,10,10,10" Margin="4,4,0,0" Padding="4,4,4,4">
            <Border.Background>
                <LinearGradientBrush EndPoint="1,0.5" StartPoint="0,0.5">
                    <GradientStop Color="AliceBlue" Offset="0"/>
                    <GradientStop Color="Bisque" Offset="1"/>
                </LinearGradientBrush>
            </Border.Background>
            <Grid >
                <Button HorizontalAlignment="Right" VerticalAlignment="Top" Width="30" Height="20"  Content="X" Background="Red" Click="Remove_Click"></Button>
                <WrapPanel Orientation="Vertical">
                <TextBox Text="{Binding Name}" Margin="10,10" Height="20"  ></TextBox>
                    <TextBox Text="{Binding City}" Margin="10,10" Height="20" ></TextBox>
                    <TextBox Text="{Binding Age}" Margin="10,10" Height="20"></TextBox>
                    <TextBox Text="{Binding Count}" Margin="10,10" Height="20" ></TextBox>
                </WrapPanel>
            </Grid>
        </Border>
    </DataTemplate>
</Window.Resources>
<Grid>
    <ItemsControl 

              Width="Auto"
              Height="Auto"
              ItemsSource="{Binding ElementName=mainWindow, Path=EmployeeCollection}"
              ItemTemplate="{StaticResource itemsTemplate}"  Background="Aqua">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel Orientation="Vertical" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
    </ItemsControl>
    <Button Content="Add" Height="23" HorizontalAlignment="Left" Margin="487,287,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="Add_Click" />
</Grid>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;

namespace DynamicAddRemovePanel
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public ObservableCollection<Employee> employeeCollection = new ObservableCollection<Employee>();

        public ObservableCollection<Employee> EmployeeCollection
        {
            get
            {
                return this.employeeCollection;
            }
            set
            {
                this.employeeCollection = value;
            }
        }
        public MainWindow()
        {
            InitializeComponent();
        }




        public class Employee
        {
            public string Name { get; set; }
            public string City { get; set; }
            public int Age { get; set; }
            public static int Count { get; set; }
            public Employee()
            {
                Count++;
            }
            public Employee(string nameArg, string cityArg, int ageArg)
            {
                this.Name = nameArg;
                this.City = cityArg;
                this.Age = ageArg;
                Count++;
           }
        }

        private void Add_Click(object sender, RoutedEventArgs e)
        {
            employeeCollection.Add(new Employee("Pritesh","Abad",22));
        }
        private void Remove_Click(object sender, RoutedEventArgs e)
        {
            var emp = (sender as FrameworkElement).DataContext as Employee;
            employeeCollection.Remove(emp);
        }


    }
}
...