以编程方式在WPF中移动TextBlocks

时间:2014-07-30 12:19:19

标签: c# wpf

我一直在阅读有关XAML的一些教程,但它对我没有帮助。我有一个空的应用程序窗口,我需要在3行中创建30个TextBox。

在胜利形式上使用,我想我会弄清楚 - 好吧,我没有。我似乎找不到如何在某些坐标上创建它们的方法。

4 个答案:

答案 0 :(得分:3)

您首先要在屏幕上放置Canvas控件,然后可以使用放置在所需Canvas.LeftCanvas.Top位置的TextBox来填充它。

尽管如此,WPF拥有比WinForms更好的布局/排列系统,并尝试使用它就像它的WinForms意味着你会错过很多让WPF如此伟大的东西,以及你会让自己的事情变得更加艰难。

WPF执行相同操作的方式是使用ItemsControl和一组对象,每个对象都包含UI需要知道的数据以供显示。

首先,您将创建一个表示每个TextBox的类

public class MyClass
{
    public string Text { get; set; }
    public int X { get; set; }
    public int Y { get; set; }
}

注意:如果您想在运行时更改属性并让UI自动更新,则此类应实现INotifyPropertyChanged

然后列出这个类,并将其绑定到ItemsControl

<ItemsControl ItemsSource="{Binding ListOfMyClass}" />

然后您想要将ItemsPanelTemplate覆盖为Canvas(根据X,Y位置定位项目的最佳WPF面板)

<ItemsControl ItemsSource="{Binding ListOfMyClass}">
    <!-- ItemsPanelTemplate -->
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Canvas />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

接下来覆盖ItemTemplate以使用TextBlock

绘制每个项目
<!-- ItemTemplate -->
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <TextBox Text="{Binding Text}" />
    </DataTemplate>
</ItemsControl.ItemTemplate>

添加ItemContainerStyle,将Canvas.Left和Canvas.Top属性绑定到对象的X,Y属性

<!-- ItemContainerStyle -->
<ItemsControl.ItemContainerStyle>
    <Style>
        <Setter Property="Canvas.Left" Value="{Binding X}" />
        <Setter Property="Canvas.Top" Value="{Binding Y}" />
    </Style>
</ItemsControl.ItemContainerStyle>

这将获取MyClass个对象的列表,并将它们渲染到画布内的屏幕,每个项目都位于指定的X,Y坐标处。

说了这么多,你确定这就是你想要的吗? WPF比WinForms有更好的布局面板,如果你不想,你不必根据X,Y坐标定位每个元素。

为了快速直观地介绍WPF的布局,我建议使用以下链接:WPF Layouts - A Visual Quick Start

此外,由于听起来您是WPF新手并且来自WinForms背景,您可能会发现这个相关问题的答案很有用:Transitioning from Windows Forms to WPF

答案 1 :(得分:1)

WPF布局涉及选择布局容器并将控件放入其中。有几种不同的容器:

  • Grid容器是用于在行和列中布置表单的强大工具。您可以完全控制每个单元格的大小,并且可以有行或列&#34; span&#34;彼此。
  • DockPanel容器可让您“停靠”#34;控制窗口或中心的边缘。您可以使用它来布局带有智能图标栏,色带,状态窗口和工具箱的窗口,例如Visual Studio本身。
  • StackPanel容器可用于将控件叠加在一起或彼此相邻
  • UniformGrid容器是容量较小的容器版本,可以使所有单元格保持相同的大小。
  • Canvas容器允许您指定X&amp;控件的Y坐标。

还有一两个,但这些是我使用过的。

使用X&amp; amp; Y坐标是表单不能很好地处理调整大小。当你支持全球化时,这可能会加剧,因为字符串的标签和外语可能会长得多。我头脑中最好的例子是西班牙语。很多英语短语在翻译成西班牙语时会更长。

Grid容器可让您最大程度地控制布局。列可以自动调整为列中最长字符串的大小,而其余列则根据需要自动调整,自动调整。你不必编写一行代码来获得这种效果;它开箱即用Grid控件中的所有内容。

如果您坚持以Winforms方式布置表单,请使用Canvas。但是,您不会从其他容器中使用更高级的布局工具中获益,尤其是Grid控件。我几乎只在我的表格中使用它。

修改

使用Canvas以外的布局控件意味着您在WPF中考虑的布局与WinForms中的布局不同。您在更高的概念级别工作,并留下有关确定屏幕上将向WPF显示特定控件的详细信息。你也没有WPF中的WinForms Anchor属性,这对我来说似乎总是很糟糕。

答案 2 :(得分:0)

如果要以网格方式放置TextBox,请使用Grid

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="50" />
        <ColumnDefinition Width="50" />
        <ColumnDefinition Width="50" />
        ...
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>

    <TextBox Grid.Row="0" Grid.Column="0" />
    <TextBox Grid.Row="0" Grid.Column="1" />
    <TextBox Grid.Row="0" Grid.Column="2" />
    ...

    <TextBox Grid.Row="1" Grid.Column="0" />
    <TextBox Grid.Row="1" Grid.Column="1" />
    <TextBox Grid.Row="1" Grid.Column="2" />
    ...
</Grid>

答案 3 :(得分:0)

WPF旨在为设计师提供强大而丰富的框架,使其与经典的winforms不同。您可以通过将TextBox控件添加到画布并更改附加属性来实现所需的功能,这是一个完整的示例说明:

<强>主窗口

<Window x:Class="WpfApplication2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Canvas Name="mainCanvas" Margin="31,-10,-31,10">
            <TextBox Name="myTextBox" Canvas.Left="131" Canvas.Top="109" Height="84" Width="135"></TextBox>
            <Button Content="Button" Height="62" Canvas.Left="271" Canvas.Top="69" Width="91" Click="Button_Click"/>
        </Canvas>
    </Grid>
</Window>

代码背后

using System.Windows;
using System.Windows.Controls;

namespace WpfApplication2
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
           myTextBox.SetValue(Canvas.LeftProperty,(double)myTextBox.GetValue(Canvas.LeftProperty)+50.0);
        }
    }
}