C# 易于访问的控件阵列

C# 易于访问的控件阵列,c#,wpf,xaml,microsoft-metro,C#,Wpf,Xaml,Microsoft Metro,我对整个XAML都是新手 我需要创建一个具有固定行数和列数(例如2x5)的表(网格),并在每个单元格中放置一个TextBlock 如何正确地执行此操作,以便轻松更改单元格的数据 例如,我想创建一个接受1个整数作为偏移量的函数: void fillDate(int offset) 并从偏移量开始递增填充单元格 i、 e.为2x5调用带有“fillData(3)”的函数将生成下表: | | |1|2 3|4|5|6|7 它没有什么特别之处,来自Silverlight/XAML背景,但可能或多

我对整个XAML都是新手

我需要创建一个具有固定行数和列数(例如2x5)的表(网格),并在每个单元格中放置一个
TextBlock

如何正确地执行此操作,以便轻松更改单元格的数据

例如,我想创建一个接受1个整数作为偏移量的函数:

void fillDate(int offset)
并从偏移量开始递增填充单元格

i、 e.为2x5调用带有“fillData(3)”的函数将生成下表:

 | | |1|2
3|4|5|6|7 

它没有什么特别之处,来自Silverlight/XAML背景,但可能或多或少会起作用。您可能需要调整API的细微差异(在记事本中编写而不使用VS handy)和未经测试,但应该为您提供入门所需的内容

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++;
        }
    }
}
编辑:根据您的注释,首先在创建控件时运行一个方法,以构建网格并填充所有文本字段,并将其存储在某种列表中:

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 int Rows=2;
私有int列=5;
私有文本块[][]文本条目;
私有void CreateTextBlocks()
{
TextEntries=新的TextBlock[行][];
对于(int-rowIndex=0;rowIndex
然后根据需要运行另一个方法来更改值:

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++;
        }
    }
}
private void fillDate(整数偏移)
{
int currentEntry=1;
对于(int-rowIndex=0;rowIndex偏移)
textEntry.Text=currentEntry.ToString();
其他的
textEntry.Text=String.Empty;
currentEntry++;
}
}
}

试试看这个。在这里,您使用ListBox作为items数组的容器,使用UniformGrid作为占位符(您可以将行数和列数绑定到类的属性,以便在运行时更改它们)

InotifyProperty已更改

    public event PropertyChangedEventHandler PropertyChanged;
    void NotifyPropertyChanged( string prop )
    {
        if( PropertyChanged != null ) 
        PropertyChanged( this , new PropertyChangedEventArgs( prop ) );
    }

}

public class MyObject
{
    public string MyField{get;set;}
}

你的代码的问题(至少我认为是你的代码的问题!:D)是我以后无法访问创建的
TextBlock
s。i、 在函数的第二次调用中。啊,是的。我忘了将它添加到网格(myGrid.Children.add(textEntry))。如果要重用现有的文本块,可以将它们存储在数组中,也可以通过网格的
子属性访问它们。@MBZ我添加了另一个实现,看看它是否有帮助。其主要思想是映射ObservableCollection(相当于一维数组)设置行中元素数的二维数组。这里Xcoord=索引%列;Ycoord=索引/列;
<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);
        ...
    }
    public event PropertyChangedEventHandler PropertyChanged;
    void NotifyPropertyChanged( string prop )
    {
        if( PropertyChanged != null ) 
        PropertyChanged( this , new PropertyChangedEventArgs( prop ) );
    }

}

public class MyObject
{
    public string MyField{get;set;}
}