如何阻止标签在WPF中堆叠

时间:2019-02-24 02:49:01

标签: c# wpf xaml

我正在创建一个程序,如果您单击该按钮,它将添加一个新标签。但是问题是,当您单击添加按钮时,标签会不断堆叠,而不是列表

这是代码

c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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;

namespace firstwpfapp
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        private void addTask(object sender, RoutedEventArgs e)
        {
            String val = input.ToString();
            Label todo = new Label();
            todo.Content = val;
            List.Children.Add(todo);
        }
    }
}

xaml

...
<Window x:Class="firstwpfapp.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:firstwpfapp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid Margin="-120,-142,0,0" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0*"/>
            <ColumnDefinition Width="5*"/>
            <ColumnDefinition Width="451*"/>
        </Grid.ColumnDefinitions>
        <StackPanel x:Name="Wrapper"Background="LightGray" Orientation="Horizontal"></StackPanel>
        <TextBox x:Name="input" Grid.Column="2" HorizontalAlignment="Left" Height="31" Margin="106,198,0,0" TextWrapping="Wrap" Text="Enter here" VerticalAlignment="Top" Width="166"/>
        <Button  Content="Button" Grid.Column="2" HorizontalAlignment="Left" Margin="106,234,0,0" VerticalAlignment="Top" Width="166" Height="26" Click="addTask"/>
        <Grid x:Name="List" Grid.Column="2" HorizontalAlignment="Left" Height="391" Margin="507,160,0,0" VerticalAlignment="Top" Width="385"/>
    </Grid>
</Window>

每次按下该按钮,列表就会一直堆叠在另一个顶部

3 个答案:

答案 0 :(得分:1)

您可以继续并将您的项目添加到ListView中,该项目将为您堆叠项目,并包括一个我们可以绑定的ItemSource,以便它将为每个新的ToDo创建行适合您的项目:

注意:我尚未测试以下内容;我在Macbook上。

  1. 将您的Wrapper StackLayout替换为:

<ListView Name="Wrapper" Grid.Row="0" Grid.ColumnSpan="3" ItemsSource="{Binding Tasks}" />

  1. 现在,创建一个名为Task.cs的新文件,在创建新类型的Task时将使用该文件(将以下内容添加到Task.cs文件中):

    public class Task { public string task { get; set;} }

  2. 让您的MainWindow继承自INotifyPropertyChanged接口INotifyPropertyChanged

    public partial class MainWindow : Window, INotifyPropertyChanged

  3. 现在将MainWindow之后的其余代码更新为:

    private ObservableCollection<Task> _tasks;
    //Tasks will store all of the tasks of type Task that we add to it 
    //as well as be bound to our ListView that will display whatever we add to our Tasks
    public ObservableCollection<Task> Tasks
    {
        get
        {
            return _tasks;
        }
    
        set
        {
            if (value != _tasks)
            {
                _tasks = value;
                OnPropertyChanged("Tasks");
            }
        }
    }
    //Here we implement OnPropertyChanged so our ObservableCollection can be notified 
    //whenever we have a new task added to or removed from Tasks (this is created when we implement INotifyPropertyChanged
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string name)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
    //Create a new Task and add it to our Tasks any time the addTask button is clicked
    private void addTask(object sender, RoutedEventArgs e)
    {
    
        Tasks.Add(new Task(input.Text));
    }
    

答案 1 :(得分:0)

替换网格

<Grid x:Name="List" Grid.Column="2" HorizontalAlignment="Left" Height="391" Margin="507,160,0,0" VerticalAlignment="Top" Width="385"/>

使用StackPanel:

<StackPanel x:Name="List" Grid.Column="2" HorizontalAlignment="Left" Height="391" Margin="507,160,0,0" VerticalAlignment="Top" Width="385"/>

将子元素添加到网格中会使它们彼此堆叠(如您所注意到的) StackPanel在前一个子元素的下方(或之后)添加新的子元素。

答案 2 :(得分:0)

尝试一下..........

XAML:

 <Grid> 
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <StackPanel VerticalAlignment="Top" HorizontalAlignment="Center"
                Orientation="Horizontal"
                Margin="0,50,0,0">
        <TextBox Name="Input"
                 Width="300"
                 VerticalAlignment="Center"
                 HorizontalAlignment="Left" />
        <Button Name="AddBtn"
                Content="Add"
                Margin="20,0,0,0"
                VerticalAlignment="Center"
                Width="100" 
                Click="AddBtn_Click"/>
    </StackPanel>
    <ListView Name="ItemListView"
              ItemsSource="{Binding Path=LabelItems, Mode=OneWay}"
              Grid.Row="1"
              HorizontalAlignment="Center"
              VerticalAlignment="Top"
              Margin="20"/>
</Grid>

C#代码:

 public partial class MainWindow : Window, INotifyPropertyChanged
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
    }

    private ObservableCollection<string> _labels = new ObservableCollection<string>();

    public ObservableCollection<string> LabelItems
    {
        get { return _labels; }
        set { _labels = value; RaisePropertyChanged(); }
    }

    private void AddBtn_Click(object sender, RoutedEventArgs e)
    {
        if(Input.Text != "" && Input.Text != null)
        {
            LabelItems.Add(Input.Text);
        }
    }


    public event PropertyChangedEventHandler PropertyChanged;

    void RaisePropertyChanged([CallerMemberName]string name = null)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(name));
        }
    }
}