gpt4 book ai didi

c# - 在 C# 中向 UI 动态添加元素

转载 作者:太空狗 更新时间:2023-10-29 20:58:36 27 4
gpt4 key购买 nike

问题

我有一个 C# 窗口,上面有一些文本字段和按钮。它开始类似于: The initial interface

当用户单击“+ 添加机器功能”按钮时,我需要创建一行新的控件并将按钮移至这些控件下方: Added machine function

如果用户点击“+Add Scale Unit”,程序需要在右侧添加一些控件: Added scale unit

尝试解决方案

我曾尝试使用 Windows 窗体的 TableLayoutPanel,但它似乎能够以奇怪的方式调整自身大小以适应其他控件,例如,它会使某些控件行比其他控件宽得多,并且会使某些行变得如此短以致于被截断关闭我的部分控件。

我也曾尝试通过简单地计算控件的相对位置,将控件本身简单地放置到窗体中。但是我觉得这是一种糟糕的编程习惯,因为它使得以后很难更改表单的布局。如果用户通过按下旁边的“X”删除行或缩放单元,此方法还需要程序找到该元素下方的每个元素并将其单独向上移动,这是非常低效的。

我的问题是:我将如何通过 Windows 窗体布局或 WPF 或其他方式创建一个动态增长/收缩的应用程序?

最佳答案

在 WPF 中你可以这样做:

public class MachineFunction
{
public string Name { get; set; }
public int Machines { get; set; }

public ObservableCollection<ScaleUnit> ScaleUnits { get; set; }

public MachineFunction()
{
ScaleUnits = new ObservableCollection<ScaleUnit>();
}
}

public class ScaleUnit
{
public string Name { get; set; }
public int Index { get; set; }

public ScaleUnit(int index)
{
this.Index = index;
}
}

Window.xaml

<Window x:Class="WpfApplication1.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">
<StackPanel>
<ItemsControl Name="lstMachineFunctions">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Text="Machine Function"/>
<TextBlock Grid.Row="0" Grid.Column="2" Text="Number of Machines"/>
<Button Grid.Row="1" Grid.Column="0" Click="OnDeleteMachineFunction">X</Button>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Name}"/>
<TextBox Grid.Row="1" Grid.Column="2" Text="{Binding Machines}"/>
</Grid>

<ItemsControl ItemsSource="{Binding ScaleUnits}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid Margin="12,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Text="Machine/Scale Unit"/>
<Button Grid.Row="1" Grid.Column="0" Click="OnDeleteScaleUnit">X</Button>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Name}"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Index, StringFormat='Scale Unit {0}'}"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<Button VerticalAlignment="Center" Click="OnAddScaleUnit">Add Scale Unit</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

<Button HorizontalAlignment="Left" Click="OnAddMachineFunction">Add Machine Function</Button>
</StackPanel>
</Window>

Window.cs

public partial class MainWindow : Window
{
public ObservableCollection<MachineFunction> MachineFunctions { get; set; }

public MainWindow()
{
InitializeComponent();

lstMachineFunctions.ItemsSource = MachineFunctions = new ObservableCollection<MachineFunction>();
}

private void OnDeleteMachineFunction(object sender, RoutedEventArgs e)
{
MachineFunctions.Remove((sender as FrameworkElement).DataContext as MachineFunction);
}

private void OnAddMachineFunction(object sender, RoutedEventArgs e)
{
MachineFunctions.Add(new MachineFunction());
}

private void OnAddScaleUnit(object sender, RoutedEventArgs e)
{
var mf = (sender as FrameworkElement).DataContext as MachineFunction;

mf.ScaleUnits.Add(new ScaleUnit(mf.ScaleUnits.Count));
}

private void OnDeleteScaleUnit(object sender, RoutedEventArgs e)
{
var delScaleUnit = (sender as FrameworkElement).DataContext as ScaleUnit;

var mf = MachineFunctions.FirstOrDefault(_ => _.ScaleUnits.Contains(delScaleUnit));

if( mf != null )
{
mf.ScaleUnits.Remove(delScaleUnit);

foreach (var scaleUnit in mf.ScaleUnits)
{
scaleUnit.Index = mf.ScaleUnits.IndexOf(scaleUnit);
}
}
}
}

关于c# - 在 C# 中向 UI 动态添加元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24728667/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com