添加/删除控件行

时间:2015-11-13 16:30:26

标签: c# wpf xaml events

我有一个面板,我的想法是让它由包含两个文本框的堆栈面板填充。当用户在左侧框中输入内容时,应在右侧生成内容,如下所示。

<StackPanel Orientation="Horizontal">
  <TextBox Name="Lefty" LostFocus="FillMyBuddy" />
  <TextBox Name="Righty" LostFocus="FillMyBuddy" />
</StackPanel>

但是,我想添加一个添加/删除行的选项,因为我希望不限制自己的数量,所以我对两点的方法有点不确定。

  1. 操纵DOM(嗯,它的XAML / WPF,但你看到我瞄准的目标)。
  2. 事件处理。
  3. 以编程方式影响窗口的标记结构是否是一个很大的禁忌?或者在运行时添加/删除面板是否可以?

    如果我希望 Righty 3号中的 Lefty 3号更改内容,推荐的方法是什么?还有什么比检查发件人和从父母那里拉出兄弟姐妹更整洁?我想为任何和所有行使用单个事件处理程序(知道操作总是在行内)。

1 个答案:

答案 0 :(得分:5)

您将需要关注MVVM,并且在代码隐藏中没有代码(以编程方式影响标记结构)文件。掌握它时,这个概念很容易,所以在开始编写代码之前要先学习它。

简而言之,您将希望拥有一个视图模型(实现INotifyPropertyChanged(INPC)的东西),它包含您的项目集合(将成为模型,或在纯MVVM中查看模型) )。在&#34; hybrid&#34; -MVVM中,您可以让您的模型实现INPC。

然后,通过使用命令,您可以实现逻辑以从列表中删除项目。您可以传递引用,引发通知,使用事件冒泡等等(它是您的首选项)实际删除该项目。就我而言,我刚刚通过了一位经理&#34;对混合动力模型进行了参考。当调用该命令(单击按钮)时,模型会调用引用以从列表中删除它自己。

执行此操作后,您可以定义DataTemplate来定义&#34;项目&#34;应该看起来像一个视图。您使用ItemsControl来显示项目集合,并绑定到其ItemsSource,以便显示项目集合。将ItemsControl.ItemTemplate设置为您创建的DataTemplate,并且绑定到ItemsSource中定义的DataTemplate.DataType类型的集合中添加的任何内容都将按照您在{{1}中指定的方式呈现}}。

在一天结束时,您应该了解MVVM设计,DataTemplate,INPC,命令,控件类型及其&#34; main&#34;属性,例如从DataContext继承的所有内容都有ItemsControl属性。

这是一个工作示例,其中更改原始字符串,将其反转并将其放在只读右侧文本框中:

Text changed, items removed, etc.

MainWindow.xaml.cs(代码隐藏)

ItemsSource

MainWindow.xaml(查看)

public partial class MainWindow : Window
{
    StructureVm _struct = new StructureVm("Test");

    public MainWindow()
    {
        InitializeComponent();

        DataContext = _struct;
    }
}

接口(有助于依赖注入)

<Window x:Class="DataTemplateWithCommands.MainWindow"
        xmlns:local="clr-namespace:DataTemplateWithCommands"
        Title="MainWindow" Height="350" Width="525" Background="Orange">
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:Model}"
                      x:Key="VmItem">
            <StackPanel Orientation="Horizontal">
                <TextBox Text="{Binding Original, UpdateSourceTrigger=PropertyChanged}" />
                <TextBox Text="{Binding Encoded}"
                         IsReadOnly="True" />
                <Button Content="X"
                        Command="{Binding RemoveMeCommand}" />
            </StackPanel>
        </DataTemplate>
    </Window.Resources>
    <Grid>
        <ItemsControl ItemsSource="{Binding Items}"
                      ItemTemplate="{StaticResource VmItem}">
        </ItemsControl>
    </Grid>
</Window>

视图模型

public interface IStructureManager
{
    bool RemoveItem(Model itemToRemove);
}

模型(不是纯MVVM,纯MVVM模型不实现INPC,并且不包含命令)

public class StructureVm : IStructureManager
{
    private readonly ObservableCollection<Model> _items;
    private readonly string _title;

    public StructureVm(string title)
    {
        _title = title;
        _items = new ObservableCollection<Model>
            {
                new Model(this, "12"),
                new Model(this, "23"),
                new Model(this, "34"),
                new Model(this, "45"),
                new Model(this, "56"),
                new Model(this, "67"),
                new Model(this, "78"),
                new Model(this, "89"),
            };
    }}

    public ObservableCollection<Model> Items
    {
        get
        {
            return _items;
        }
    }

    public string Title
    {
        get
        {
            return _title;
        }
    }

    public bool RemoveItem(Model itemToRemove)
    {
        return _items.Remove(itemToRemove);
    }
}

RelayCommand implementation

从现在开始,您需要做的就是将控件的属性更改为您满意的任何内容,并将其称为“好”。这个例子可能很难看,但是我把它作为练习让你弄清楚WPF控件的其他属性/属性。