我在WPF工作 - 我的应用程序中有button
click event handler
。当我点击按钮时,它的事件处理程序在网格中生成一个名为grids
的新行。在这个新的行中,我想以编程方式添加另一个网格,以便在此行的网格中添加Label,Button和TextBox。
当我执行我的代码时,它只生成一个texboxes!标签和按钮显示一次!这里的代码和图片是:请随时询问我的查询是否不清楚!
int r =0;
private void button2_Click(object sender, RoutedEventArgs e)
{
TextEdit text1; Button button1; Grid grid1;
grids.RowDefinitions.Add(new RowDefinition());
text1 = new TextEdit();
text1.SetValue(Grid.ColumnProperty, 1);
text1.SetValue(Grid.RowProperty, r);
button1 = new Button();
button1.Content = "Left + " + r;
button1.Click += new RoutedEventHandler(button1_Click);
button1.SetValue(Grid.ColumnProperty, 1);
button1.SetValue(Grid.RowProperty, r);
grid1 = new Grid();
grid1.SetValue(Grid.ColumnProperty, 1);
grids.RowDefinitions.Add(new RowDefinition());
grid1.SetValue(Grid.RowProperty, r);
grids.Children.Add(button1);
grids.Children.Add(text1);
r = r + 1;
}
的修改
int r =0;
private void button2_Click(object sender, RoutedEventArgs e)
{
db obj = new db();
var query = from p in obj.TableA select p ;
foreach(var a in query.ToList())
{
TextEdit text1; Button button1; Grid grid1;
grids.RowDefinitions.Add(new RowDefinition());
text1 = new TextEdit();
text1.SetValue(Grid.ColumnProperty, 1);
text1.SetValue(Grid.RowProperty, r);
button1 = new Button();
button1.Content = a.name;
button1.Click += new RoutedEventHandler(button1_Click);
button1.SetValue(Grid.ColumnProperty, 1);
button1.SetValue(Grid.RowProperty, r);
grid1 = new Grid();
grid1.SetValue(Grid.ColumnProperty, 1);
grids.RowDefinitions.Add(new RowDefinition());
grid1.SetValue(Grid.RowProperty, r);
grids.Children.Add(button1);
grids.Children.Add(text1);
r = r + 1;}
}
答案 0 :(得分:21)
确定。删除所有代码并从头开始。
如果你正在使用WPF,你真的需要The WPF Mentality
作为一般规则,您几乎从不在WPF中的过程代码中创建或操作UI元素。 这就是XAML的用途。
这是在WPF中执行您所要求的正确方法(在完整的工作示例中):
<Window x:Class="MiscSamples.ItemsControlSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
Title="ItemsControlSample" Height="300" Width="300">
<DockPanel>
<Button Content="Add New Row" Command="{Binding AddNewRowCommand}"
DockPanel.Dock="Bottom"/>
<ItemsControl ItemsSource="{Binding Data}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" Background="Gainsboro" BorderThickness="1" Margin="2">
<!-- This is the Inner Grid for each element, which is represented in Brown color in your picture -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width=".2*"/>
<ColumnDefinition Width=".2*"/>
</Grid.ColumnDefinitions>
<Label Content="{Binding Label1Text}"
Margin="2"/>
<Button Content="Button1"
Command="{Binding DataContext.Command1, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"
Grid.Column="1" Margin="2"/>
<Button Content="Button2"
Command="{Binding DataContext.Command2, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
CommandParameter="{Binding}"
Grid.Column="2" Margin="2"/>
<dxe:TextEdit Text="{Binding Text}"
Grid.Row="1" Grid.ColumnSpan="3"
Margin="2"/>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Template>
<ControlTemplate TargetType="ItemsControl">
<ScrollViewer CanContentScroll="True">
<ItemsPresenter/>
</ScrollViewer>
</ControlTemplate>
</ItemsControl.Template>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</DockPanel>
</Window>
代码背后:
public partial class ItemsControlSample : Window
{
public ItemsControlSample()
{
InitializeComponent();
DataContext = new ItemsControlSampleViewModel();
}
}
视图模型:
public class ItemsControlSampleViewModel
{
public ObservableCollection<ItemsControlSampleData> Data { get; set; }
public Command AddNewRowCommand { get; set; }
public Command<ItemsControlSampleData> Command1 { get; set; }
public Command<ItemsControlSampleData> Command2 { get; set; }
public ItemsControlSampleViewModel()
{
var sampledata = Enumerable.Range(0, 10)
.Select(x => new ItemsControlSampleData()
{
Label1Text = "Label1 " + x.ToString(),
Text = "Text" + x.ToString()
});
Data = new ObservableCollection<ItemsControlSampleData>(sampledata);
AddNewRowCommand = new Command(AddNewRow);
Command1 = new Command<ItemsControlSampleData>(ExecuteCommand1);
Command2 = new Command<ItemsControlSampleData>(ExecuteCommand2);
}
private void AddNewRow()
{
Data.Add(new ItemsControlSampleData() {Label1Text = "Label 1 - New Row", Text = "New Row Text"});
}
private void ExecuteCommand1(ItemsControlSampleData data)
{
MessageBox.Show("Command1 - " + data.Label1Text);
}
private void ExecuteCommand2(ItemsControlSampleData data)
{
MessageBox.Show("Command2 - " + data.Label1Text);
}
}
数据项:
public class ItemsControlSampleData
{
public string Label1Text { get; set; }
public string Text { get; set; }
}
助手班:
public class Command : ICommand
{
public Action Action { get; set; }
public string DisplayName { get; set; }
public void Execute(object parameter)
{
if (Action != null)
Action();
}
public bool CanExecute(object parameter)
{
return IsEnabled;
}
private bool _isEnabled = true;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
}
public event EventHandler CanExecuteChanged;
public Command(Action action)
{
Action = action;
}
}
public class Command<T>: ICommand
{
public Action<T> Action { get; set; }
public void Execute(object parameter)
{
if (Action != null && parameter is T)
Action((T)parameter);
}
public bool CanExecute(object parameter)
{
return IsEnabled;
}
private bool _isEnabled = true;
public bool IsEnabled
{
get { return _isEnabled; }
set
{
_isEnabled = value;
if (CanExecuteChanged != null)
CanExecuteChanged(this, EventArgs.Empty);
}
}
public event EventHandler CanExecuteChanged;
public Command(Action<T> action)
{
Action = action;
}
}
结果:
ObservableCollection
添加新项目,WPF会自动创建绑定到该项目的新UI元素。ViewModel<T>
中实现,然后可以为任何类型的数据项重用。 Command
和Command<T>
也是可写入的可重用类,可以在任何MVVM框架中找到,例如Prism,MVVM Light或Caliburn.Micro。File -> New Project -> WPF Application
中,然后自行查看结果。答案 1 :(得分:6)
在xaml代码中代码背后实际上要容易得多..
我的Xaml代码:
<Window x:Class="WpfAddGridWithStackPanel.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>
<Grid x:Name="Grid_Grid" Margin="0,0,0,32">
<Grid>
<ScrollViewer VerticalScrollBarVisibility="Auto">
<Grid x:Name="Grid_Grid" Margin="0,0,0,32"/>
</ScrollViewer>
<Button x:Name="btn_Add" Height="32" DockPanel.Dock="Bottom" VerticalAlignment="Bottom" Content="Add New Row" Click="btn_Add_Click" Width="150" HorizontalAlignment="Left" UseLayoutRounding="True" />
<Button x:Name="btn_Remove" Height="32" DockPanel.Dock="Bottom" VerticalAlignment="Bottom" Content="Remove last Row" Click="btn_Remove_Click" Width="150" HorizontalAlignment="Right" />
</Grid>
</Window>
代码背后:
public partial class MainWindow : Window
{
int num = 0;
public MainWindow()
{
InitializeComponent();
}
void btn1_Click(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
void btn2_Click(object sender, RoutedEventArgs e)
{
throw new NotImplementedException();
}
private void btn_Remove_Click(object sender, RoutedEventArgs e)
{
try
{
Grid_Grid.RowDefinitions.RemoveAt(Grid_Grid.RowDefinitions.Count - 1);
Grid_Grid.Children.RemoveAt(Grid_Grid.Children.Count - 1);
num--;
}
catch { }
}
private void btn_Add_Click(object sender, RoutedEventArgs e)
{
StackPanel stack = new StackPanel();
DockPanel dock = new DockPanel();
Label lbl = new Label();
Button btn1 = new Button();
Button btn2 = new Button();
TextBox txt1 = new TextBox();
stack.Children.Add(dock);
stack.Children.Add(txt1);
dock.Children.Add(lbl);
dock.Children.Add(btn2);
dock.Children.Add(btn1);
#region StackPanel Properties
stack.Background = Brushes.LightGray;
#endregion
#region DockPanel Content Properties
lbl.Content = "Label " + (num + 1).ToString();
lbl.Height = 32;
lbl.Width = 100;
lbl.FontSize = 12;
lbl.SetValue(DockPanel.DockProperty, Dock.Left);
lbl.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
btn1.Content = "Butten 1";
btn1.Height = 32;
btn1.Width = 100;
btn1.FontSize = 12;
btn1.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
btn1.SetValue(DockPanel.DockProperty, Dock.Right);
btn1.Click += new RoutedEventHandler(btn1_Click);
btn2.Content = "Butten 2";
btn2.Height = 32;
btn2.Width = 100;
btn2.FontSize = 12;
btn2.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
btn2.SetValue(DockPanel.DockProperty, Dock.Right);
btn2.Click += new RoutedEventHandler(btn2_Click);
#endregion
#region TextBox Properties
txt1.Text = "Text " + (num + 1).ToString();
txt1.Height = 32;
txt1.Width = double.NaN;
txt1.FontSize = 12;
txt1.Padding = new Thickness(0, 7, 0, 7);
#endregion
Grid_Grid.RowDefinitions.Add(new RowDefinition());
Grid_Grid.RowDefinitions[num].Height = new GridLength(66, GridUnitType.Pixel);
Grid_Grid.Children.Add(stack);
stack.SetValue(Grid.RowProperty, num);
num++;
}
}