Hi!
I create custom control (root element is stacklayout) and have collection of custom elements. When I set collection to control from viewmodel I have started fill root element by my items: create some template for every item in collection and add it to children of root item. Here is template of my item:
(black - grid, red - layout, green - boxview)
Problem consist in long loading time (for ex. creation of all children are more than 2 seconds when I have around 10 items (2 max lines of text)).
What could be the problem?
Here is code of my control:
public class ContentView : StackLayout
{
public static BindableProperty ContentsProperty = BindableProperty.Create(propertyName: "Contents", returnType: typeof(List<ContentItem>), declaringType: typeof(ContentView), defaultValue: null, propertyChanged: ContentsChanged);
public List<ContentItem> Contents
{
get { return (List<ContentItem>)GetValue(ContentsProperty); }
set { SetValue(ContentsProperty, value); }
}
private static void ContentsChanged(BindableObject sender, object oldValue, object newValue)
{
var control = sender as ContentView;
if (control != null)
{
if (oldValue != null)
{
control.ClearContent();
}
if (newValue != null)
{
control.ApplyNewContent();
}
}
}
private void ClearContent()
{
this.Children.Clear();
}
private async void ApplyNewContent()
{
System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
sw.Start();
if (this.Contents != null && this.Contents.Any())
{
for (int i = 0; i < this.Contents.Count; i++)
{
View newView = null;
if (this.Contents[i].Image != null)
{
newView = this.CreateImage(this.Contents[i].Image);
}
else if (this.Contents[i].Text != null)
{
newView = this.CreateLabel(this.Contents[i].Text, i != this.Contents.Count - 1);
}
if (newView != null)
{
this.Children.Add(newView);
}
}
}
System.Diagnostics.Debug.WriteLine(sw.Elapsed);
}
private View CreateLabel(TopicText topicText, bool isNeedAddLine)
{
Grid result = null;
if (topicText != null && !string.IsNullOrEmpty(topicText.Text))
{
result = new Grid()
{
Padding = new Thickness(0),
RowSpacing = 0,
ColumnSpacing = 15,
};
var textColor = Color.FromHex("5c5c5c");
var elementColor = Color.FromHex("03a9f4");
if (topicText.IsNote)
{
textColor = Color.FromHex("61b300");
elementColor = Color.FromHex("61b300");
}
else if (topicText.IsAttention)
{
textColor = Color.FromHex("f44336");
elementColor = Color.FromHex("f44336");
}
// create 2 columns
result.ColumnDefinitions = new ColumnDefinitionCollection()
{
new ColumnDefinition() { Width = GridLength.Auto},
new ColumnDefinition(),
};
// grid for first colum
var firstColumnGrid = new Grid()
{
Padding = new Thickness(0),
RowSpacing = 0
};
firstColumnGrid.RowDefinitions = new RowDefinitionCollection()
{
new RowDefinition() { Height = GridLength.Auto},
new RowDefinition(),
};
// round box in top left part of item template
var roundedBox = new RoundedBoxView()
{
WidthRequest = 20,
HeightRequest = 20,
StrokeWidth = 5,
StrokeColor = elementColor,
BackgroundColor = Color.White,
};
firstColumnGrid.Children.Add(roundedBox);
// add bottom line if it isn't last element in list
if (isNeedAddLine)
{
// vertical separator in left part of item template
var contentView = new Frame()
{
Padding = new Thickness(1, -2, 0, -2),
};
var line = new BoxView()
{
Color = elementColor,
WidthRequest = 3,
HeightRequest = 0,
HorizontalOptions = LayoutOptions.Center,
};
contentView.Content = line;
firstColumnGrid.Children.Add(contentView, 0, 1);
}
var label = new ExtendedLabel()
{
FontSize = 15,
Text = topicText.Text.Trim() + "\n",
TextColor = textColor,
Margin = new Thickness(0, -10, 0, 0),
};
result.Children.Add(firstColumnGrid);
result.Children.Add(label, 1, 0);
}
return result;
}
}
Thanks!