Xamarin:如何删除网格中特定行中的项目
Posted
技术标签:
【中文标题】Xamarin:如何删除网格中特定行中的项目【英文标题】:Xamarin: How to remove an item in a specific row in Grid 【发布时间】:2022-01-02 10:16:44 【问题描述】:我有一个网格,我正在尝试删除特定行中的项目。它在一个循环中,然后当它转到第二行时,它会删除第二行中的项目,并删除第一行中的项目。如何调整以仅删除我想要的行?
请注意,我要做的是将第一行复制到第二行,仅解决 pow (b²),在第三行中我将复制第二行,但解决 -4 * 5 (-4 *一)。
这是正在发生的事情的预览。
This 是我扩充这些行的代码,以了解:
它首先进入if(fields == null)
,因为是pow,然后进入else
:
for (int i = 0; i < qntLines; i++)
string field = lines[i].Substring(0, lines[i].IndexOf('#'));
string operation = lines[i].Substring(lines[i].IndexOf('#') + "#".Length);
CreateResultLine(field, operation, i, listTexts);
private void CreateResultLine(string field, string operation, int i, List<string> listTexts)
string[] fields = null;
List<string> texts = new List<string>();
string text = string.Empty;
dynamic textResult;
int count = new int();
if (field.Contains(','))
fields = field.Split(',', (char)StringSplitOptions.RemoveEmptyEntries);
if (fields == null)
text = listTexts[int.Parse(field)];
text = RemovePow(text);
texts.Add(text);
textResult = ExecuteOperation(texts, operation);
gridFrame.Children.RemoveAt(int.Parse(field) + 1);
gridFrame.Children.Add(new Label() Text = textResult.ToString(), HorizontalTextAlignment = TextAlignment.Center,
TextColor = Color.Blue, HorizontalOptions = LayoutOptions.Center , int.Parse(field) + 1, i);
else
foreach (var item in fields)
string noPow = string.Empty;
noPow = RemovePow(listTexts[int.Parse(item)]);
texts.Add(noPow);
++count;
textResult = ExecuteOperation(texts, operation);
for (int i2 = int.Parse(fields[0]); i2 <= int.Parse(fields[1]);)
gridFrame.Children.RemoveAt(int.Parse(fields[0]));
++i2;
gridFrame.Children.Add(new Label() Text = textResult.ToString(), HorizontalTextAlignment = TextAlignment.Center,
TextColor = Color.Blue, HorizontalOptions = LayoutOptions.Center , int.Parse(fields[0]) + 1, i);
【问题讨论】:
我没有研究过你的代码,但我会做一个一般性的评论:与其试图操纵gridFrame.Children
,为什么不简单地设置someItem.IsVisible = false;
,其中someItem
是网格单元格你想隐藏吗?然后为了显示不同的结果,有一个不同的项目,以IsVisible = false
开头,更新它的文本,然后设置它的IsVisible=true
。对我来说,操纵视图的可见性比按摩布局的子级更容易。
另一个想法:当你创建每个项目时,如果你以后需要访问它,然后以某种方式“记住”它。如果在 xaml 中创建了一个网格行,您可以给它一个 x:name
属性。如果在 c# 中创建了一个网格行,那么您可以使用您想要记住的那些创建一个列表字段(因此很容易知道正确的索引),或者您可以使用给定的键添加到字典中,以找到它稍后通过键字符串。无论哪种方式,您都不再需要 循环 遍历孩子。您直接转到您关心的项目。
现在看看你的代码有什么问题。我不打算详细阅读,但有一个事实让我眼前一亮。当您执行多个RemoveAt
s 时,一旦删除第一个,就会更改所有索引以供以后使用RemoveAt
s。一种解决方法:“最后一个”删除它们。一种方法是反转循环:从最高索引开始并使用递减--
。 (而不是从具有增量的最低索引开始。)另一种解决方案是,当您找到要删除的每个项目时,不要删除它。将其放入“toRemove”列表中。然后,当您找到所有这些时,在每个上使用 Remove
。
对于您的最后一条评论,您能给我看一些代码示例吗?我不明白我怎么能像你说的那样做。
我添加了一个答案,显示了更好的方法。
【参考方案1】:
这是一个使用网格单元格的完整示例。
这个概念是您首先创建所有单元格。在这里,我在每个网格单元格中使用Label
。为了更容易理解,我将每个单元格的文本设置为我分配给它的“CellNumber”。一旦你明白发生了什么,只需将一个空字符串""
作为初始值。
为了方便查找单元格,Dictionary
包含它们。 CellNumber(row, column)
将key
提供给该字典,以查找相应的单元格。
Calculate
按钮对单元格进行了一些更改,因此您可以了解如何操作。
一旦初始化,我建议不要添加或删除单元格(网格的孩子)。相反,显示或隐藏一个单元格。在这里,您可以通过更改 Label
的 Text
来做到这一点。对于其他类型的View
s,您可以将View.IsVisible
更改为true 或false。
MainPage.xaml:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ManipulateGridChildren.MainPage">
<Grid x:Name="Formulas" BackgroundColor="#A0A0A0"
RowSpacing="2" ColumnSpacing="2" Padding="2"
ColumnDefinitions="*,*,*,*,*,*,*,*"
RowDefinitions="40,40,40,Auto">
<Button Grid.Row="3" Text="Calc" Command="Binding CalcCommand" />
</Grid>
</ContentPage>
MainPage.xaml.cs:
using System.Collections.Generic;
using Xamarin.Forms;
namespace ManipulateGridChildren
public partial class MainPage : ContentPage
const int NRows = 3;
static int NColumns = 8;
const int MaxColumns = 100;
private Dictionary<int, Label> cells = new Dictionary<int, Label>();
public MainPage()
InitializeComponent();
AddCells();
CalcCommand = new Command(Calculate);
BindingContext = this;
public Command CalcCommand get; set;
private void Calculate()
SetCellText(0, 0, "A");
SetCellText(0, 2, "B");
SetCellText(1, 0, "C");
SetCellText(2, 3, "D");
SetCellBackground(2, 3, Color.Pink)
private void SetCellText(int row, int column, string text)
cells[CellNumber(row, column)].Text = text;
private void SetCellBackground(int row, int column, Color color)
cells[CellNumber(row, column)].BackgroundColor = color;
private void AddCells()
// Grid rows and columns are numbered from "0".
for (int row = 0; row < NRows; row++)
for (int column = 0; column < NColumns; column++)
var cell = AddCell(row, column);
cells[CellNumber(row, column)] = cell;
// Add "frames" around some rows.
// AFTER adding the cells, so drawn on top.
AddFrame(0, 1, 0, NColumns);
AddFrame(1, 2, 0, NColumns);
private Label AddCell(int row, int column)
var cell = new Label();
// For debugging - show where each cell is.
// Once you understand, change this to an empty string.
cell.Text = $"CellNumber(row, column)";
cell.BackgroundColor = Color.White;
cell.HorizontalTextAlignment = TextAlignment.Center;
cell.VerticalTextAlignment = TextAlignment.Center;
Formulas.Children.Add(cell, column, row);
return cell;
// Assign unique number to each cell.
private int CellNumber(int row, int column)
return row * MaxColumns + column;
private void AddFrame(int row, int rowSpan, int column, int columnSpan)
var rect = new Xamarin.Forms.Shapes.Rectangle
Stroke = new SolidColorBrush(Color.Black),
StrokeThickness = 2
;
Formulas.Children.Add(rect, column, column + columnSpan, row, row + rowSpan);
【讨论】:
谢谢,我按照这个想法创建了一个网格列表,然后只显示它是否可见。【参考方案2】:对你想要达到的目标有点困惑,但这里有一个建议。
我建议采用 MVVM 模式。在代码中操作 UI 并不是最好的主意。
<ContentPage.BindingContext>
<local: MainViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<ListView ItemSource=Binding ListOfItems>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Label Text=Binding ./>
<ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
MainViewModel.cs
public class MainViewModel : INotifyPropertyChanged
public ObservableCollection<string> ListOfItems get;set; = new ObservableCollection<string>();
public void DeleteAnItem(string s)
ListOfItems.Remove(s);
public void AddItem(string s)
ListOfItems.Add(s);
public void RemoveAtIndex(int i)
ListOfItems.RemoveAt(i);
#region TheRestOfPropertyChanged
...
#endregion
您对列表所做的每项更改都将在您的 UI 中显示。
【讨论】:
以上是关于Xamarin:如何删除网格中特定行中的项目的主要内容,如果未能解决你的问题,请参考以下文章
如何删除 Material UI DataGrid (Reactjs) 中的特定行