Resizeable multiple TextBoxes

有些话、适合烂在心里 提交于 2019-12-24 16:14:13

问题


I'm going to create some program that resizeable (with drag) multiple Textboxes.

But, I don't know how to build this layout. Is there know how to create drag layout?


回答1:


It's not entirely clear what your exact specification is here. But the drawing makes it look like you want some cells within the grid to have grab handles for varying width, while others do not. For this purpose, you should be able to use the GridSplitter object.

For example:

<Window x:Class="TestSO36334781GridSplitter.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:p="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">

  <StackPanel>
    <Border BorderBrush="Black" BorderThickness="1">
      <Grid>
        <Grid.Resources>
          <p:Style TargetType="GridSplitter">
            <Setter Property="HorizontalAlignment" Value="Right"/>
            <Setter Property="VerticalAlignment" Value="Stretch"/>
            <Setter Property="Width" Value="5"/>
            <Setter Property="Height" Value="10"/>
            <Setter Property="Background" Value="Black"/>

            <!-- Offset the splitter visually so it's centered over the gridline -->
            <Setter Property="RenderTransform">
              <Setter.Value>
                <TranslateTransform X="2.5" Y="0"/>
              </Setter.Value>
            </Setter>
          </p:Style>
          <p:Style TargetType="TextBox">
            <Setter Property="Height" Value="30"/>
          </p:Style>
        </Grid.Resources>
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition/>
          <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
          <ColumnDefinition/>
          <ColumnDefinition/>
          <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <TextBlock Text="Label1" Grid.Column="0"/>
        <TextBlock Text="Label1" Grid.Column="1"/>
        <TextBlock Text="Label1" Grid.Column="2"/>

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

        <GridSplitter Grid.Row="1" Grid.Column="0"/>
        <GridSplitter Grid.Row="1" Grid.Column="1"/>

        <TextBox Grid.Row="2" Grid.ColumnSpan="3" Text="A wide textbox here"/>
      </Grid>
    </Border>
  </StackPanel>
</Window>

The above shows a grid with three TextBox controls in the middle row, the widths of which can be modified by the user by dragging the GridSplitter between each of them. The labels above them (i.e. the TextBlock objects) are moved/resized as well, as they share the same column with each respective TextBox.

A fourth TextBox is shown, spanning three columns in the last row, to show how you can still have other grid elements independent of the splitters. I assume you can modify the basic idea to suit your specific needs.

Note that it's important you provide your specific formatting for the splitter objects, and that they appear after the controls they share grid elements with, so that they are above those controls in the z-order.

See also this Stack Overflow question: WPF user controlled grid column width

Addendum:

As hinted at in the (now deleted) comments by Joey, it is possible to place splitter controls without them having to share the cell with (and possibly obscuring) other elements in the grid. The following XAML snippet (i.e. just the Grid element) shows how that would work:

<Grid>
  <Grid.Resources>
    <p:Style TargetType="GridSplitter">
      <Setter Property="HorizontalAlignment" Value="Right"/>
      <Setter Property="VerticalAlignment" Value="Stretch"/>
      <Setter Property="Width" Value="5"/>
      <Setter Property="Height" Value="10"/>
      <Setter Property="Background" Value="Black"/>
    </p:Style>
    <p:Style TargetType="TextBox">
      <Setter Property="Height" Value="30"/>
    </p:Style>
  </Grid.Resources>
  <Grid.RowDefinitions>
    <RowDefinition/>
    <RowDefinition/>
    <RowDefinition/>
  </Grid.RowDefinitions>
  <Grid.ColumnDefinitions>
    <ColumnDefinition/>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition/>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition/>
  </Grid.ColumnDefinitions>

  <TextBlock Text="Label1" Grid.Column="0"/>
  <TextBlock Text="Label1" Grid.Column="2"/>
  <TextBlock Text="Label1" Grid.Column="4"/>

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

  <GridSplitter Grid.Row="1" Grid.Column="1" ResizeBehavior="PreviousAndNext"/>
  <GridSplitter Grid.Row="1" Grid.Column="3" ResizeBehavior="PreviousAndNext"/>

  <TextBox Grid.Row="2" Grid.ColumnSpan="5" Text="A wide textbox here"/>
</Grid>

The above eliminates the need for the RenderTransform, as each GridSplitter winds up centered in its own column. The ResizeBehavior is set to PreviousAndNext, so that dragging the splitter affects not the width of the column in which the splitter is contained, but instead the widths of the columns immediately before and after it.


It's possible that you could apply a DataGrid control in this scenario and get it to do what you want. But there's nothing in your question that suggests to me you need the full feature set of a DataGrid, or even that you'll be happy with some of the constraints that would involve (such as the way headings are formatted, and whether you can include other fixed-width elements in the layout).



来源:https://stackoverflow.com/questions/36334781/resizeable-multiple-textboxes

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!