Reputation: 27582
I'm quite new to whole XAML thing.
I need to create a table (grid) with constant number of rows and columns (e.g 2x5) and put a TextBlock
in each cell.
How can I do this properly, so I can change the data of cells easily?
for example, I want to create a function which accepts 1 integer as offset:
void fillDate(int offset)
and fills the cells starting from offset incrementally.
i.e. calling the function with `fillData(3)' for a 2x5 would generate the following table:
| | |1|2
3|4|5|6|7
Upvotes: 1
Views: 137
Reputation: 375
Try look to this. Here you use ListBox as container for your items array and UniformGrid as placeholder (you can bind number of rows and columns to properties of your class to alter them at run-time)
<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>
and in code you just need to alter elements of your collection
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{ ... }
}
setItem
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;}
}
Upvotes: 2
Reputation: 23198
It's nothing special, and coming from a Silverlight/XAML background, but will probably more or less work. You might need to tweak for slight API differences (writing in notepad without VS handy) and untested, but should give you what you need to get started.
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++;
}
}
}
EDIT: Just realized that you might be wanting a TextBlock with no text in the "empty" cells, in which case substitute the inner loop's code with:
TextBlock textEntry = new TextBlock();
Grid.SetRow(textEntry, rowIndex);
Grid.SetColumn(textEntry, columnIndex);
if (currentEntry > offset)
textEntry.Text = currentEntry.ToString();
currentEntry++;
EDIT: Based on your comment, first run a method when you create your control to build the grid and populate all the textfields and store them in a listing of some sort:
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;
}
}
}
Then subsequently run another method to alter the values as desired:
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++;
}
}
}
Upvotes: 0