我正在尝试制作包含一些按钮(1,4,8)的网格。
<Window x:Class="WpfApplication9.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.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
</Grid.ColumnDefinitions>
<!--<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0"></Button>
<Button Grid.Row="0" Grid.Column="1"></Button>
<Button Grid.Row="1" Grid.Column="0"></Button>
<Button Grid.Row="1" Grid.Column="1"></Button>
</Grid>-->
<ItemsControl ItemsSource="{Binding TheList}" x:Name="MyGrid" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Height="Auto" Grid.Row="1">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
</Grid>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding One}">1</Button>
<Button Command="{Binding Four}">4</Button>
<Button Command="{Binding Eight}">8</Button>
</StackPanel>
</Grid>
代码:
using GalaSoft.MvvmLight.Command;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Collections.ObjectModel;
namespace WpfApplication9
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
///
public partial class MainWindow : Window
{
public class ViewModelTest : INotifyPropertyChanged
{
private ObservableCollection<Button> theList;
public ObservableCollection<Button> TheList
{
get { return theList; }
set { theList = value; NotifyPropertyChanged("TheList"); }
}
public ViewModelTest()
{
One = new RelayCommand(() => OneButton());
Four = new RelayCommand(() => FourButton());
Eight = new RelayCommand(() => EightButton());
//TheList.Clear();
//for (int i = 0; i < 4; i++)
//{
// System.Windows.Controls.Button newBtn = new Button();
// newBtn.Content = i.ToString();
// newBtn.Name = "Button" + i.ToString();
// TheList.Add(newBtn);
//}
}
public ICommand One { get; set; }
public ICommand Four { get; set; }
public ICommand Eight { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
public void OneButton()
{
TheList = new ObservableCollection<Button>();
for (int i = 0; i < 1; i++)
{
Button btn = new Button();
System.Windows.Controls.Button newBtn = new Button();
newBtn.Content = i.ToString();
newBtn.Name = "Button" + i.ToString();
TheList.Add(newBtn);
}
}
public void FourButton()
{
TheList = new ObservableCollection<Button>();
for (int i = 0; i < 4; i++)
{
Button btn = new Button();
System.Windows.Controls.Button newBtn = new Button();
newBtn.Content = i.ToString();
newBtn.Name = "Button" + i.ToString();
TheList.Add(newBtn);
}
//MyGrid.Children.Clear();
//MyGrid.ColumnDefinitions.Clear();
//MyGrid.RowDefinitions.Clear();
//MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
//MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
//MyGrid.RowDefinitions.Add(new RowDefinition());
//MyGrid.RowDefinitions.Add(new RowDefinition());
//for (int row =0;row<MyGrid.ColumnDefinitions.Count;row++)
//{
// for (int column=0;column<MyGrid.ColumnDefinitions.Count;column++)
// {
// System.Windows.Controls.Button newBtn = new Button();
// newBtn.Content = row.ToString() + column.ToString();
// newBtn.Name = "Button" + row.ToString()+column.ToString();
// newBtn.SetValue(Grid.ColumnProperty,column);
// newBtn.SetValue(Grid.RowProperty, row);
// MyGrid.Children.Add(newBtn);
// }
//}
}
public void EightButton()
{
TheList = new ObservableCollection<Button>();
for (int i = 0; i < 8; i++)
{
Button btn = new Button();
System.Windows.Controls.Button newBtn = new Button();
newBtn.Content = i.ToString();
newBtn.Name = "Button" + i.ToString();
TheList.Add(newBtn);
}
//MyGrid.Children.Clear();
//MyGrid.ColumnDefinitions.Clear();
//MyGrid.RowDefinitions.Clear();
//MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
//MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
//MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
//MyGrid.ColumnDefinitions.Add(new ColumnDefinition());
//MyGrid.RowDefinitions.Add(new RowDefinition());
//MyGrid.RowDefinitions.Add(new RowDefinition());
//for (int row = 0; row < MyGrid.ColumnDefinitions.Count; row++)
//{
// for (int column = 0; column < MyGrid.ColumnDefinitions.Count; column++)
// {
// System.Windows.Controls.Button newBtn = new Button();
// newBtn.Content = row.ToString() + column.ToString();
// newBtn.Name = "Button" + row.ToString() + column.ToString();
// newBtn.SetValue(Grid.ColumnProperty, column);
// newBtn.SetValue(Grid.RowProperty, row);
// MyGrid.Children.Add(newBtn);
// }
//}
}
}
public MainWindow()
{
DataContext = new ViewModelTest();
InitializeComponent();
}
}
但是显示有问题。在这种情况下,如何动态地在itemcontrol中创建新的列和行。
答案 0 :(得分:0)
好的,从哪里开始......
你在这里遇到了几个问题。
TheList是一个ObservableCollection,因此不需要在TheList属性中使用'NotifyPropertyChanged'。并且不需要theList成员变量。只需将以下内容用于您的财产:
public ObservableCollection TheList {get;组; }
但是,在您的代码后面,在单击其中一个按钮之前,“TheList”不会被初始化。因此,你的XAML绑定到一个null对象,所以几乎不绑定任何东西,无论你在绑定之后将'TheList'更改为什么,你仍然绑定为null。要解决此问题,请确保在InitializeComponents()调用之前在构造函数中初始化TheList。将构造函数更改为以下内容:
public MainWindow()
{
TheList = new ObservableCollection<Button>();
DataContext = new ViewModelTest();
InitializeComponent();
}
此外,您设置TheList = new ObservableCollection<Button>()
的所有位置只是将指针更改为其他位置,因此Binding再次被破坏。不要重新初始化TheList,只需执行TheList.Clear();
,然后使用TheList.Add(newBtn);
所以,看起来你有一堆没有高度的RowDefinitions,我猜这些只是占位符?您可以将网格命名为x:Name="MyInternalGrid"
,然后当您添加到TheList
时,将行添加到MyInternalGrid
也是如此。因此,当致电TheList.Clear();
时,也可以通过调用MyInternalGrid.RowDefinitions.Clear();
来清除您的gridRows。然后,每当您致电TheList.Add(newBtn);
时,请使用MyInternalGrid.RowDefinitions.Add(new RowDefinition{Height=20});
向您的网格添加另一行。执行此操作时,请确保将正确的行分配给newBtn。在将Grid.SetRow(newBtn, MyInternalGrid.RowDefinitions.Count);
添加到newBtn
之前TheList
。这就是我的意思,改变你的方法来模仿下面重构的EightButton()
方法:
public void EightButton()
{
TheList.Clear();
MyInternalGrid.RowDefinitions.Clear();
for (int i = 0; i < 8; i++)
{
Button newBtn = new Button();
newBtn.Content = i.ToString();
newBtn.Name = "Button" + i.ToString();
Grid.SetRow(newBtn, MyInternalGrid.RowDefinitions.Count);
MyInternalGrid.RowDefinitions.Add(new RowDefinition{Height=20});
TheList.Add(newBtn);
}
}
或者,您可能只是不想担心所有网格行,并在<StackPanel>
中添加<Grid>
并动态添加所有按钮<StackPanel>
。首先清除堆栈面板MyStackPanel.Children.Clear();
,然后在循环中添加新按钮MyStackPanel.Children.Add(newBtn);
首页其中一些有帮助。