我对整个 XAML 很陌生。
我需要创建一个具有恒定行数和列数(例如 2x5)的表格(网格),并TextBlock
在每个单元格中放置一个。
我怎样才能正确地做到这一点,所以我可以轻松地更改单元格的数据?
例如,我想创建一个接受 1 个整数作为偏移量的函数:
void fillDate(int offset)
并从偏移量开始填充单元格。
即使用 `fillData(3)' 为 2x5 调用函数将生成下表:
| | |1|2
3|4|5|6|7
我对整个 XAML 很陌生。
我需要创建一个具有恒定行数和列数(例如 2x5)的表格(网格),并TextBlock
在每个单元格中放置一个。
我怎样才能正确地做到这一点,所以我可以轻松地更改单元格的数据?
例如,我想创建一个接受 1 个整数作为偏移量的函数:
void fillDate(int offset)
并从偏移量开始填充单元格。
即使用 `fillData(3)' 为 2x5 调用函数将生成下表:
| | |1|2
3|4|5|6|7
试试看这个。在这里,您使用ListBox作为项目数组的容器,使用UniformGrid作为占位符(您可以将行数和列数绑定到类的属性以在运行时更改它们)
<Window x:Class=MyWindowClass ... >
...
<ListBox
ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=MyWindowClass}, Path=myItems}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Columns="{Binding Path=ColumnsInArray}"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=MyField}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Window>
在代码中,您只需要更改集合的元素
class MyWindowClass: INotifyPropertyChanged
{
public MyWindowClass():base()
{
...
InitializeComponent();
myItems = new ObservableCollection<MyObject>();
myItems.Add(new MyObject);// First Element
myItems.Add(new MyObject);// Second Element
...
myItems.Add(new MyObject);// Last Element
...
}
int columns=5;
public int ColumnsInArray
{
get{return columns;}
set {columns=value; NotifyPropertyChanged("ColumnsInArray");}
}
public ObservableCollection<MyObject> myItems
{
get{ ... }
set{ ... }
}
设置项
void setItem(int index,MyObject newObject)
{
...
myItems[index]=newObject;
...
}
void setItem(int x, int y, MyObject newObject)
{
...
int index = y*columns+x;
setItem(index,newObject);
...
}
INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
void NotifyPropertyChanged( string prop )
{
if( PropertyChanged != null )
PropertyChanged( this , new PropertyChangedEventArgs( prop ) );
}
}
public class MyObject
{
public string MyField{get;set;}
}
这没什么特别的,并且来自 Silverlight/XAML 背景,但可能或多或少会起作用。您可能需要针对细微的 API 差异进行调整(在没有 VS 的情况下在记事本中编写)并且未经测试,但应该为您提供入门所需的内容。
private void fillDate(int offset)
{
int rows = 2;
int columns = 5;
int currentEntry = 1;
for(int rowIndex = 0; rowIndex < rows; rowIndex++)
{
for (int columnIndex = 0; columnIndex < columns; columnIndex++)
{
if (currentEntry > offset)
{
TextBlock textEntry = new TextBlock();
textEntry.Text = currentEntry.ToString();
Grid.SetRow(textEntry, rowIndex);
Grid.SetColumn(textEntry, columnIndex);
}
currentEntry++;
}
}
}
编辑:刚刚意识到您可能想要一个在“空”单元格中没有文本的 TextBlock,在这种情况下,将内部循环的代码替换为:
TextBlock textEntry = new TextBlock();
Grid.SetRow(textEntry, rowIndex);
Grid.SetColumn(textEntry, columnIndex);
if (currentEntry > offset)
textEntry.Text = currentEntry.ToString();
currentEntry++;
编辑:根据您的评论,在创建控件时首先运行一个方法来构建网格并填充所有文本字段并将它们存储在某种列表中:
private int Rows = 2;
private int Columns = 5;
private TextBlock[][] TextEntries;
private void CreateTextBlocks()
{
TextEntries = new TextBlock[Rows][];
for (int rowIndex = 0; rowIndex < rows; rowIndex++)
{
entries[rowIndex] = new string[columns];
for (int columnIndex = 0; columnIndex < columns; columnIndex++)
{
TextBlock textEntry = new TextBlock();
Grid.SetRow(textEntry, rowIndex);
Grid.SetColumn(textEntry, columnIndex);
myGrid.Children.Add(textEntry);
TextEntries[rowIndex][columnIndex] = textEntry;
}
}
}
然后随后运行另一种方法来根据需要更改值:
private void fillDate(int offset)
{
int currentEntry = 1;
for(int rowIndex = 0; rowIndex < Rows; rowIndex++)
{
for (int columnIndex = 0; columnIndex < Columns; columnIndex++)
{
TextBlock textEntry = TextEntries[rowIndex][columnIndex]
if (currentEntry > offset)
textEntry.Text = currentEntry.ToString();
else
textEntry.Text = String.Empty;
currentEntry++;
}
}
}