目前我正在创建用于将数据列表显示为Grid的自定义数据网格。我从Github获得了一些示例源。基于示例源,我已根据我的要求进行了修改。但是在访问listview数据时我遇到了一些问题 1.当我点击那个特定的单元格时,我能够改变特定的单元格背景颜色。但是需要获得相关的行进行一些计算。
我需要区分标记的细胞和未标记的细胞。一旦我点击了单元格。
我的问题是如何在同一时间点击单元格区分单元格以进行计算Output Screen shot
Code Snap:
public class DataGrid : StackLayout
{
#region binding properties
// public static BindableProperty ItemClickCommandProperty = BindableProperty.Create<DataGrid, ICommand>(x => x.ItemClickCommand, null);
public static readonly BindableProperty HeaderBackgroundProperty =
BindableProperty.Create<DataGrid, Color>((p) => p.HeaderBackground, Color.Aqua);
public static readonly BindableProperty HeaderTextColorProperty =
BindableProperty.Create<DataGrid, Color>((p) => p.HeaderTextColor, Color.Black);
public static readonly BindableProperty EvenRowBackgroundProperty =
BindableProperty.Create<DataGrid, Color>((p) => p.EvenRowBackground, Color.White);
public static readonly BindableProperty OddRowBackgroundProperty =
BindableProperty.Create<DataGrid, Color>((p) => p.OddRowBackground, Color.White);
public static readonly BindableProperty EvenRowForegroundProperty =
BindableProperty.Create<DataGrid, Color>((p) => p.EvenRowForeground, Color.Black);
public static readonly BindableProperty OddRowForegroundProperty =
BindableProperty.Create<DataGrid, Color>((p) => p.OddRowForeground, Color.Black);
public static readonly BindableProperty ColumnsProperty =
BindableProperty.Create<DataGrid, ColumnCollection>((p) => p.Columns, null, BindingMode.TwoWay, null, UpdateColumns);
public static readonly BindableProperty ItemsSourceProperty =
BindableProperty.Create<DataGrid, IEnumerable>((p) => p.ItemsSource, null, BindingMode.TwoWay, null, DrawDataGrid);
public static readonly BindableProperty RowHeightProperty =
BindableProperty.Create<DataGrid, double>((p) => p.RowHeight, 40);
public static readonly BindableProperty HeaderHeightProperty =
BindableProperty.Create<DataGrid, double>((p) => p.HeaderHeight, 40);
public static readonly BindableProperty IsSortableProperty =
BindableProperty.Create<DataGrid, bool>((p) => p.IsSortable, true);
public static readonly BindableProperty HeaderFontSizeProperty =
BindableProperty.Create<DataGrid, double>((p)=>p.HeaderFontSize,13);
private static void DrawDataGrid(BindableObject bindable, IEnumerable oldValue, IEnumerable newValue)
{
if ((bindable as DataGrid).Columns.Count > 0 && !(bindable as DataGrid).hasInitialized)
(bindable as DataGrid).InitilizeUI();
}
private static void UpdateColumns(BindableObject bindable, ColumnCollection oldValue, ColumnCollection newValue)
{
if (!(bindable as DataGrid).hasInitialized && newValue.Count > 0)
(bindable as DataGrid).InitilizeUI();
}
#endregion
#region properties
public Color HeaderBackground
{
get { return (Color)GetValue(HeaderBackgroundProperty); }
set { SetValue(HeaderBackgroundProperty, value); }
}
public Color HeaderTextColor
{
get { return (Color)GetValue(HeaderTextColorProperty); }
set { SetValue(HeaderTextColorProperty, value); }
}
public Color EvenRowBackground
{
get { return (Color)GetValue(EvenRowBackgroundProperty); }
set { SetValue(EvenRowBackgroundProperty, value); }
}
public Color OddRowBackground
{
get { return (Color)GetValue(OddRowBackgroundProperty); }
set { SetValue(OddRowBackgroundProperty, value); }
}
public Color EvenRowForeground
{
get { return (Color)GetValue(EvenRowForegroundProperty); }
set { SetValue(EvenRowForegroundProperty, value); }
}
public Color OddRowForeground
{
get { return (Color)GetValue(OddRowForegroundProperty); }
set { SetValue(OddRowForegroundProperty, value); }
}
public IList ItemsSource
{
get { return (IList)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public ColumnCollection Columns
{
get { return (ColumnCollection)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
public double HeaderFontSize
{
get { return (double)GetValue(HeaderFontSizeProperty); }
set { SetValue(HeaderFontSizeProperty,value); }
}
public double RowHeight
{
get { return (double)GetValue(RowHeightProperty); }
set { SetValue(RowHeightProperty, value); }
}
public double HeaderHeight
{
get { return (double)GetValue(HeaderHeightProperty); }
set { SetValue(HeaderHeightProperty, value); }
}
public bool IsSortable
{
get { return (bool)GetValue(IsSortableProperty); }
set { SetValue(IsSortableProperty, value); }
}
#endregion
#region fields
bool hasInitialized = false;
Dictionary<int, SortingOrder> SortingOrders;
ListView listView;
#endregion
#region ctor
public DataGrid()
{
SortingOrders = new Dictionary<int, SortingOrder>();
this.Columns = new ColumnCollection();
this.Padding = 5;
this.Spacing = 0;
this.BackgroundColor = Color.White;
this.VerticalOptions = LayoutOptions.Fill;
listView = new ListView()
{
SeparatorVisibility = SeparatorVisibility.None,
ItemTemplate = new DataTemplate(GetRowTemplate),
};
// listView.ItemTapped += this.OnItemTapped;
listView.ItemTapped += (sender, e) =>
{
if (e.Item != null)
{
var selectedItem = e.Item;
}
// await Xamarin.Forms.Page.DisplayAlert();
};
listView.ItemSelected += (s, e) =>
{
listView.SelectedItem = null;
};
}
#endregion
//public ICommand ItemClickCommand
//{
// get { return (ICommand)this.GetValue(ItemClickCommandProperty); }
// set { this.SetValue(ItemClickCommandProperty, value); }
//}
//private void OnItemTapped(object sender, ItemTappedEventArgs e)
//{
// if (e.Item != null && this.ItemClickCommand != null && this.ItemClickCommand.CanExecute(e))
// {
// this.ItemClickCommand.Execute(e.Item);
// listView.SelectedItem = null;
// }
//}
public void InitilizeUI()
{
hasInitialized = true;
if (IsSortable)
{
for (int i = 0; i < Columns.Count; i++ )
SortingOrders.Add(i, SortingOrder.NotDetermined);
}
listView.ItemsSource = ItemsSource;
listView.RowHeight = (int)RowHeight;
this.Children.Add(GetHeader());
if (Device.OS == TargetPlatform.Android)
{
ScrollView sv = new ScrollView();
sv.Content = listView;
this.Children.Add(sv);
}
else
this.Children.Add(listView);
}
protected virtual Grid GetHeader()
{
Grid header = new Grid()
{
HeightRequest = HeaderHeight,
Padding = new Thickness(1),
HorizontalOptions = LayoutOptions.FillAndExpand,
RowSpacing = 0,
ColumnSpacing = 1,
BackgroundColor = Color.Black,
};
header.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(HeaderHeight, GridUnitType.Absolute) });
foreach (var col in Columns)
{
header.ColumnDefinitions.Add(new ColumnDefinition() { Width = col.Width });
}
for (int i = 0; i < Columns.Count; i++)
{
Label lb = new Label()
{
Text = Columns[i].Title,
VerticalOptions = LayoutOptions.CenterAndExpand,
HorizontalOptions = LayoutOptions.CenterAndExpand,
TextColor = HeaderTextColor,
FontAttributes = Xamarin.Forms.FontAttributes.Bold,
XAlign = TextAlignment.Center,
YAlign = TextAlignment.Center,
LineBreakMode = Xamarin.Forms.LineBreakMode.WordWrap,
FontSize=HeaderFontSize,
};
StackLayout sl = new StackLayout()
{
BackgroundColor = HeaderBackground,
VerticalOptions = LayoutOptions.FillAndExpand,
Orientation = StackOrientation.Horizontal,
Children = { lb }
};
if (IsSortable)
{
var orderingIcon = new Label()
{
VerticalOptions = LayoutOptions.Center,
Text = " ",
};
Columns[i].Params = orderingIcon;
sl.Children.Add(orderingIcon);
string property = Columns[i].DataProperty;
string title = Columns[i].Title;
var tgr = new TapGestureRecognizer();
tgr.Tapped += (s, e) => {
var col = Columns.FirstOrDefault(x=> x.DataProperty == property && x.Title == title);
SortItems(Columns.IndexOf(col));
};
sl.GestureRecognizers.Add(tgr);
}
header.Children.Add(sl);
Grid.SetColumn(sl, i);
}
return header;
}
bool isEven = false;
bool first = true;
object GetRowTemplate()
{
KowalskiViewCell row = new KowalskiViewCell();
Grid rowGrid = new Grid()
{
BackgroundColor = Color.Black,
RowSpacing = 0,
ColumnSpacing = 1,
Padding = new Thickness(1, first ? 1 : 0, 1, 1)
};
first = false;
for (int i = 0; i < this.Columns.Count; i++)
rowGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = Columns[i].Width });
int i1 = 0;
for (int i = 0; i < this.Columns.Count; i++)
{
i1++;
ContentView cell = new ContentView()
{
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
BackgroundColor = (isEven) ? EvenRowBackground : OddRowBackground
};
if(Columns[i].CellTemplate!= null)
{
View v = Columns[i].CellTemplate.CreateContent() as View;
v.HorizontalOptions = Columns[i].HorizontalContentAlignment;
cell.Content = v;
}
else if (Columns[i].DataProperty != null)
{
Label text = new Label()
{
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = Columns[i].HorizontalContentAlignment,
TextColor = (isEven) ? OddRowForeground : EvenRowForeground,
FontSize = 12,
};
//Here implemeting Logic
if (Columns[i].DataProperty == "Name" || Columns[i].DataProperty == "Goal" || Columns[i].DataProperty == "Achieved" || Columns[i].DataProperty == "Net")
text.SetBinding(Label.TextProperty, new Binding(Columns[i].DataProperty, BindingMode.TwoWay));
var tgr = new TapGestureRecognizer();
var property = Columns[i].DataProperty;
var textval = text.GetValue(Label.TextProperty);
tgr.Tapped += (s, e) =>
{
if (property != "Name" && property != "Goal" && property != "Achieved" && property != "Net")
{
cell.BackgroundColor = Color.Green;
text.FontSize = 24;
text.TextColor = Color.White;
text.Text = i1.ToString();
}
};
cell.GestureRecognizers.Add(tgr);
cell.Content = text;
}
rowGrid.Children.Add(cell);
Grid.SetColumn(cell, i);
}
isEven = !isEven;
row.View = rowGrid;
return row;
}
private void SortItems(int propertyIndex)
{
if (ItemsSource == null || ItemsSource.Count <= 1)
return;
List<Object> item = new List<Object>();
foreach (var itm in ItemsSource)
item.Add(itm);
List<Object> sortedItems;
if (!IsSortable)
throw new InvalidOperationException("This DataGrid is not sortable");
if (Columns[propertyIndex].DataProperty == null)
throw new InvalidOperationException("Please set the DataProperty property of Column");
if (SortingOrders[propertyIndex] != SortingOrder.Descendant)
{
int i = 0;
var itm = item[0].GetType().GetRuntimeProperty(Columns[propertyIndex].DataProperty).GetValue(item[0]);
if (itm is decimal)
i++;
if (itm is double)
i++;
sortedItems = item.OrderByDescending((x) => x.GetType().GetRuntimeProperty(Columns[propertyIndex].DataProperty).GetValue(x)).ToList();
SortingOrders[propertyIndex] = SortingOrder.Descendant;
(Columns[propertyIndex].Params as Label).Text = "▼";
}
else
{
sortedItems = item.OrderBy((x) => x.GetType().GetRuntimeProperty(Columns[propertyIndex].DataProperty).GetValue(x)).ToList();
SortingOrders[propertyIndex] = SortingOrder.Ascendant;
(Columns[propertyIndex].Params as Label).Text = "▲";
}
foreach (var column in Columns)
{
if ((column.Params as Label).Text!= null && Columns[propertyIndex] != column )
(column.Params as Label).Text = " ";
}
isEven = false;
listView.ItemsSource = sortedItems;
}
}