【问题标题】:Creating a variable number of TextBox'es on a WPF form在 WPF 表单上创建可变数量的 TextBox'es
【发布时间】:2014-10-06 20:51:11
【问题描述】:

我想在 WPF 窗口上创建任意数量的标签和文本框。这样的事情在 WinForms 中很容易做到,我还以为我知道了如何在 WPF 中做到这一点,但我得到了奇怪的结果。

即我想要在视觉上发生的事情在下面(嘲笑)。新控件的数量和内容是任意的,可能是从文本文件中获取的。如果有大量控件,还存在使表单可滚动的问题,但首先要做的是。

所以我将 VS 创建的默认网格命名为“grdWiz”,并在我的窗口中创建了以下实用程序函数。粗鲁,我知道,但首先我想确保事情正常进行,然后才能美化。 更新:我现在使用 Canvas 对象而不是 Grid,并使用 Canvas 类型而不是 InkCanvas 类型来尝试设置位置。见下文:

    private int nInputs = 0;

    private void AddInput(string defLabel, string defValue)
    {
        Label newLabel = new Label() { Name = "lblConf" + nInputs };
        TextBox newText = new TextBox() { Name = "tbConf" + nInputs };
        grdWiz.Children.Add(newLabel);
        Canvas.SetLeft(newLabel, 0);
        Canvas.SetTop(newLabel, nInputs * 30);
        newLabel.Width = grdWiz.Width / 3;
        grdWiz.Children.Add(newText);
        Canvas.SetLeft(newText, grdWiz.Width / 3);
        Canvas.SetTop(newText, nInputs * 30);
        newText.Width = grdWiz.Width * 0.6666;
        newText.Height = 30;
        newText.Text = defValue;
        nInputs++;
    }

在按钮单击代码中,我执行以下操作:

    thatInitialLabel.Visibility = Visibility.Hidden;
    AddInput("Main Course:", "Grits");
    AddInput("Dessert:", "Apple Pie");
    AddInput("Fun activity to be had afterwards:", "Sleep");

我得到的是这样的:

我在做一些明显错误的事情,但我不知道是什么。此外,我将不再对 GUI 框架的相对优点发表意见。可以说我是these 中的一员。

【问题讨论】:

  • 您的控件应添加为画布的子项。我认为一个简单的Canvas 控件就足够了。您可以使用ScrollViewer,将Canvas 放在此滚动查看器中,然后将控件添加到画布。希望当控件填充到可见边界之外时,滚动条会出现并让用户滚动查看隐藏部分。
  • 不,<Grid />Grid。将其替换为<Canvas></Canvas>
  • WPF 可以让你做到和 WinForms 一样(基本上),但数据绑定和模板也更强大和更易于维护。您的选择。
  • 那篇文章很有趣。我明白你来自哪里,但是为了放弃进步而放弃进步对我来说似乎有点愚蠢(尤其是在项目开始时,你似乎在哪里)......无论如何,我会留下我的答案以防它对未来的读者有用。如果你想谈谈 MVVM。我很乐意和你聊天。我没有在您的代码中看到明显的缺陷,但是 WPF 并不是要以这种方式编写的,所以真的很难说。也许Children.Add 最后?布局引擎可能不会接收更新。
  • 所以你知道,CanvasScrollViewer 通常不会混用。您可能想尝试StackPanel,以便它为您完成布局。顺便说一句,这就是 ListView 在后台使用的(默认情况下)。

标签: c# wpf xaml visual-studio-2012 user-interface


【解决方案1】:

好吧,你找到了问题的根源:WPF 不是 WinForms

没有看到父 XAML,我无法确定您当前的问题是什么。如果没有正确的父控件,您正在使用可能没有任何效果的附加属性。话虽如此,有一个更简单的方法。

首先,创建一个为您的数据建模的类;说:

public class Input
{
    public string Label {get; set;}
    public string Value {get; set;}
}

不讲如何设置MVVM:MVVM: Tutorial from start to finish?

这样做:

<ListView ItemsSource="{Binding InputCollection}">
   <ListView.ItemTemplate>
      <DataTemplate>
         <StackPanel Orientation="Horizontal">
             <TextBlock Text="{Binding Label}"/>
             <TextBox Text="{Binding Value}"/>
         </StackPanel>
      </DataTemplate>
   </ListView.ItemTemplate>
</ListView>

执行以下操作:

  1. 设置一个 ListView 填充 ViewModel 中的“InputCollection”属性,这可能是一个ObservableCollection&lt;Input&gt;
  2. 使每个项目成为一个水平堆栈面板

    一个。有一个文本块绑定到项目的“标签”属性

    b.有一个文本框绑定到项目的“值”属性

将其与等效的 WinForms 代码进行比较。我认为它更加更清晰,更易于维护和理解,并且总体而言,是更好的实践。在这种情况下,我强烈反对使用 WinForms 让生活“更轻松”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2015-08-14
    相关资源
    最近更新 更多