Creating Grid at Runtime through code in Xamarin - xaml

I have code as per attached that builds a Xamrin Grid virtually in code. The problem that I have not been able to resolve is Events that will be triggered when entering data into a cell.
Here is the output:
Output 1
Output 2
The purpose of this post is to create an event that can be invoked to take action when data is entered into any of the cells created at runtime in the grid.
<?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="VarGridSample.MainPage">
<ScrollView>
<StackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center">
<Label
Text="Variable Grid"
FontSize="32"
HorizontalOptions="Center" />
<Label
Text="I am attempting to build a Grid at runtime to allow for variable rows and columns. The Grid has been initially defined in the Content Page. The Grid is built in the code based on the number of rows and columns requested. Entry controls are built for each cell. The problem is how to build the Events for each cell...ANY IDEAS?"
FontSize="18"
HorizontalOptions="Center" />
<Entry x:Name="Rows"
Text="{Binding Rows }"
HorizontalOptions="Center" Placeholder="Enter Total Rows" WidthRequest="150" />
<Entry x:Name="Cols"
Text="{Binding Rows }"
HorizontalOptions="Center" Placeholder="Enter Total Columns" WidthRequest="150" />
<Button x:Name="BuildGrid"
Text="Build Grid" HorizontalOptions="Center" Clicked="BuildGrid_Clicked" />
<Grid x:Name="VarGrid">
</Grid>
</StackLayout>
</ScrollView>
</ContentPage>
Below is the C# code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace VarGridSample
{
public partial class MainPage : ContentPage
{
private int rows { get; set; }
private int cols { get; set; }
private int cellcntr = 0;
public MainPage()
{
InitializeComponent();
}
private void BuildGrid_Clicked(object sender, EventArgs e)
{
rows = Int32.Parse(Rows.Text);
cols = Int32.Parse(Cols.Text);
for (int rowIndex = 0; rowIndex < rows; rowIndex++)
{
VarGrid.RowDefinitions.Add(new RowDefinition());
}
for (int rowIndex = 0; rowIndex < rows; rowIndex++)
{
for (int colIndex = 0; colIndex < cols; colIndex++)
{
var entry = new Entry
{
Text = "cell" + (cellcntr).ToString(),
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center
};
VarGrid.Children.Add(entry, colIndex, rowIndex);
cellcntr++;
}
}
}
}
}

You can add this to MainPage.xaml.cs:
private void BuildGrid_Clicked(object sender, EventArgs e)
{
rows = Int32.Parse(Rows.Text);
cols = Int32.Parse(Cols.Text);
for (int rowIndex = 0; rowIndex < rows; rowIndex++)
{
VarGrid.RowDefinitions.Add(new RowDefinition());
}
for (int rowIndex = 0; rowIndex < rows; rowIndex++)
{
for (int colIndex = 0; colIndex < cols; colIndex++)
{
var entry = new Entry
{
Text = "cell" + (cellcntr).ToString(),
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Center,
};
//add the event
entry.TextChanged += Entry_TextChanged;
VarGrid.Children.Add(entry, colIndex, rowIndex);
cellcntr++;
}
}
}
private void Entry_TextChanged(object sender, TextChangedEventArgs e)
{
Console.WriteLine(e.OldTextValue);
var entry = (Entry)sender;
var parent= (Grid)entry.Parent;
Console.WriteLine(parent.Children.Count);
}

Related

Xamarin - XAML Grid UI overwriting on each other

I am creating a UI using a grid in Xamarin which I have put in StackLayout.
Below is the following code for xaml.
program.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="LoginPage.Page">
<ContentPage.Content>
<StackLayout Orientation="Vertical">
<StackLayout BackgroundColor="#3a4851">
<Label Text="Identifications" TextColor="White" FontSize="15" Margin="10" />
</StackLayout>
<StackLayout>
<Grid x:Name="identificationGridLayout" HorizontalOptions="Center"></Grid>
</StackLayout>
<StackLayout BackgroundColor="#3a4851">
<Label Text="Deciles" TextColor="White" FontSize="15" Margin="10" />
</StackLayout>
<StackLayout>
<Grid x:Name="decileGridLayout" HorizontalOptions="Center"></Grid>
</StackLayout>
</StackLayout>
</ContentPage.Content>
</ContentPage>
I am creating the Grid header and data programatically.
program.cs
public partial class Page : ContentPage
{
private LoadingPopUp popUp;
private Repository repository = new Repository();
private JObject jResult;
private List<string> rowHeader;
private List<PrescriberIdentitifcation> prescriberIdentificationValue;
private List<PrescriberDecile> prescriberDecileValue;
public Page() { InitializeComponent(); }
public Page(string guid)
{
InitializeComponent();
FetchDataForDetail(guid);
}
async void FetchDataForDetail(string guid)
{
try
{
popUp = new LoadingPopUp("Loading data ...");
await PopupNavigation.PushAsync(popUp);
//Get Identification Data for prescriber
JObject identificationResult = await GetRepositoryDetailData(guid);
var identificationdata = JsonConvert.DeserializeObject<PrescriberIdentificationList>(identificationResult.ToString());
prescriberIdentificationValue = identificationdata.value;
int index = 0;
foreach (var obj in identificationResult["value"])
{
prescriberIdentificationValue[index].vcm_type_name = (string)obj["vcm_type#OData.Community.Display.V1.FormattedValue"];
index++;
}
drawIdentificationGrid();
//Get Deciles Data for prescriber
JObject decileResult = await GetRepositoryDetailData(guid);
var deciledata = JsonConvert.DeserializeObject<PrescriberIdentificationList>(decileResult.ToString());
prescriberIdentificationValue = deciledata.value;
Debug.WriteLine("data prescriberIdentificationValue : " + prescriberIdentificationValue);
drawDecilesGrid();
await PopupNavigation.PopAllAsync();
}
catch (Exception ex) {
Debug.WriteLine("error in identification loading : " + ex.Message);
await PopupNavigation.PopAllAsync();
}
}
public async Task<JObject> GetRepositoryDetailData(string guid, string entity, string filter)
{
try
{
jResult = await repository.Retrieve(GlobalVariables.AuthToken, entity, filter + guid);
return jResult;
}
catch (Exception err)
{
Debug.WriteLine(err.Message);
await PopupNavigation.PopAllAsync();
await DisplayAlert("Error", "Oops something went wrong", "Ok");
}
return jResult;
}
void drawIdentificationGrid()
{
try
{
rowHeader = new List<string>{"Type", "Number", "License State", "Sampleability","Expiration Date","License Status" };
drawGridHeader(identificationGridLayout,1, rowHeader.Count,rowHeader);
for (int rowIndex = 1; rowIndex <= prescriberIdentificationValue.Count; rowIndex++)
{
var datatypeLabel = new Label { Text = prescriberIdentificationValue[rowIndex-1].vcm_type_name.ToString(),FontSize=12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
var datanumberLabel = new Label { Text = prescriberIdentificationValue[rowIndex-1].vcm_name.ToString(),FontSize=12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
var datalicenseStateLabel = new Label { Text = (prescriberIdentificationValue[rowIndex-1]._vcm_licensestate_value != null) ? prescriberIdentificationValue[rowIndex-1]._vcm_licensestate_value : "-" , FontSize=12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
var datasampleabiltiyLabel = new Label { Text = (prescriberIdentificationValue[rowIndex - 1].vcm_sampleability == false) ? "No": "Yes", FontSize=12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
var dataexpirationDateLabel = new Label { Text = (prescriberIdentificationValue[rowIndex-1].vcm_expirationdate != null) ? prescriberIdentificationValue[rowIndex-1].vcm_expirationdate : "-", FontSize=12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
Debug.WriteLine("data datatypeLabel {0} datanumberLabel {1} datalicenseStateLabel {2} datasampleabiltiyLabel {3} dataexpirationDateLabel {4} rowIndex {5}",datatypeLabel.Text,datanumberLabel.Text,datalicenseStateLabel.Text, datasampleabiltiyLabel.Text, dataexpirationDateLabel.Text, rowIndex);
identificationGridLayout.Children.Add(datatypeLabel, 0, rowIndex);
identificationGridLayout.Children.Add(datanumberLabel, 1, rowIndex);
identificationGridLayout.Children.Add(datalicenseStateLabel, 2, rowIndex);
identificationGridLayout.Children.Add(datasampleabiltiyLabel, 3, rowIndex);
identificationGridLayout.Children.Add(dataexpirationDateLabel, 4, rowIndex);
}
}
catch (Exception ex) { Debug.WriteLine("Error in drawing Identifications: "+ ex.Message);}
}
void drawDecilesGrid()
{
try
{
rowHeader = new List<string>{"Quarter", "Decile Type", "Decile", "Rank","Organization Type" };
drawGridHeader(decileGridLayout,1, rowHeader.Count, rowHeader);
//for (int rowIndex = 1; rowIndex <= prescriberIdentificationValue.Count; rowIndex++)
//{
// var datatypeLabel = new Label { Text = prescriberIdentificationValue[rowIndex - 1].vcm_type_name.ToString(), FontSize = 12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
// var datanumberLabel = new Label { Text = prescriberIdentificationValue[rowIndex - 1].vcm_name.ToString(), FontSize = 12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
// var datalicenseStateLabel = new Label { Text = (prescriberIdentificationValue[rowIndex - 1]._vcm_licensestate_value != null) ? prescriberIdentificationValue[rowIndex - 1]._vcm_licensestate_value : "-", FontSize = 12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
// var datasampleabiltiyLabel = new Label { Text = (prescriberIdentificationValue[rowIndex - 1].vcm_sampleability == false) ? "No" : "Yes", FontSize = 12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
// var dataexpirationDateLabel = new Label { Text = (prescriberIdentificationValue[rowIndex - 1].vcm_expirationdate != null) ? prescriberIdentificationValue[rowIndex - 1].vcm_expirationdate : "-", FontSize = 12, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
// Debug.WriteLine("data datatypeLabel {0} datanumberLabel {1} datalicenseStateLabel {2} datasampleabiltiyLabel {3} dataexpirationDateLabel {4} rowIndex {5}",datatypeLabel.Text,datanumberLabel.Text,datalicenseStateLabel.Text, datasampleabiltiyLabel.Text, dataexpirationDateLabel.Text, rowIndex);
// identificationGridLayout.Children.Add(datatypeLabel, 0, rowIndex);
// identificationGridLayout.Children.Add(datanumberLabel, 1, rowIndex);
// identificationGridLayout.Children.Add(datalicenseStateLabel, 2, rowIndex);
// identificationGridLayout.Children.Add(datasampleabiltiyLabel, 3, rowIndex);
// identificationGridLayout.Children.Add(dataexpirationDateLabel, 4, rowIndex);
//}
}
catch (Exception ex) { Debug.WriteLine("Error in drawing Identifications: "+ ex.Message);}
}
void drawGridHeader(Grid gridLayout, int rowIndexLength, int columnIndexLength, List<string> rowHeaders)
{
try
{
gridLayout.RowDefinitions = new RowDefinitionCollection();
gridLayout.ColumnDefinitions = new ColumnDefinitionCollection();
for (int rowIndex = 0; rowIndex < rowIndexLength; rowIndex++)
{
gridLayout.RowDefinitions.Add(new RowDefinition());
}
for (int columnIndex = 0; columnIndex <= columnIndexLength; columnIndex++)
{
gridLayout.ColumnDefinitions.Add(new ColumnDefinition());
}
for (int i = 0; i < columnIndexLength; i++)
{
var label = new Label { Text = rowHeaders[i], FontSize = 14, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
identificationGridLayout.Children.Add(label, i, 0);
}
}
catch (Exception ex) { Debug.WriteLine("Error in drawing grid header: "+ ex.Message);}
}
}
}
drawGridHeader() is common to creating Header for different grids. Data for the cell is passed in different functions and grid reference is passed to it.
Ex: -
rowHeader = new List<string>{"Quarter", "Decile Type", "Decile", "Rank","Organization Type" };
drawGridHeader(decileGridLayout,1, rowHeader.Count, rowHeader);
But after fetching the data, The Grid is over writing on each other.
I tried creating manual grid with row item and they are stacking properly in order but when programmatically doing it, grid is stacking upon each other.
It should been below the Label Decile.
Inside the last for-loop in drawGridHeader(), you're not referencing the passed in grid when adding the labels:
for (int i = 0; i < columnIndexLength; i++)
{
var label = new Label { Text = rowHeaders[i], FontSize = 14, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center };
// This references the wrong Grid
// identificationGridLayout.Children.Add(label, i, 0);
gridLayout.Children.Add(label, i, 0);
}

Windows Phone 8.1 - Daily Calendar and issue

I was trying to make daily calendar and I create this:
xaml:
<Page
x:Class="Calendar.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:Calendar"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Pivot x:Name="CalendarPivot" Title="Pivot" SelectionChanged="CalendarPivot_SelectionChanged">
</Pivot>
</Grid>
<Page.BottomAppBar>
<CommandBar>
<AppBarButton x:Name="TodayAppBarButton" Label="dziś" Click="TodayAppBarButton_Click">
<AppBarButton.Icon>
<FontIcon x:Name="TodayFontIcon" Glyph="" FontSize="10" FontFamily="Segoe WP"/>
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton x:Name="ChooseDateAppBarButton" Label="wybierz" Icon="Calendar" Click="ChooseDateAppBarButton_Click">
<FlyoutBase.AttachedFlyout>
<DatePickerFlyout DatePicked="DatePickerFlyout_DatePicked"/>
</FlyoutBase.AttachedFlyout>
</AppBarButton>
</CommandBar>
</Page.BottomAppBar>
c#:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Navigation;
namespace Calendar
{
public sealed partial class MainPage : Page
{
bool pivotClear = false;
public MainPage()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var monthDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("month.abbreviated");
SetCalendar(DateTimeOffset.Now);
TodayFontIcon.Glyph = DateTimeOffset.Now.Day + " " + monthDatefmt.Format(DateTimeOffset.Now);
}
private void SetCalendar(DateTimeOffset startDate)
{
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
var dayOfWeekDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("dayofweek.full");
var dayMonthYearDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("day month year");
for (int i = -4; i < 5; i++)
{
PivotItem pivotItem = new PivotItem();
DateTimeOffset date = new DateTimeOffset();
date = startDate.AddDays(i);
pivotItem.Tag = date.Month + "/" + date.Day + "/" + date.Year;
if (date.Date == DateTimeOffset.Now.Date)
{
pivotItem.Header = loader.GetString("Today");
}
else
{
pivotItem.Header = dayOfWeekDatefmt.Format(date).ToLower();
}
CalendarPivot.Items.Add(pivotItem);
}
CalendarPivot.SelectedIndex = 4;
CalendarPivot.Title = dayMonthYearDatefmt.Format(startDate).ToUpper();
}
private void CalendarPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
Debug.WriteLine("change started" + CalendarPivot.SelectedIndex);
if (!pivotClear)
{
var sdatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("dayofweek.full");
var dayMonthYearDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("day month year");
PivotItem selectedPivotItem = CalendarPivot.SelectedItem as PivotItem;
DateTimeOffset selectedPivotItemDate = new DateTimeOffset();
selectedPivotItemDate = DateTimeOffset.Parse(selectedPivotItem.Tag as string);
CalendarPivot.Title = dayMonthYearDatefmt.Format(selectedPivotItemDate).ToUpper();
PivotItem lastPivotItem = CalendarPivot.Items.Last() as PivotItem;
DateTimeOffset lastPivotItemDate = new DateTimeOffset();
lastPivotItemDate = DateTimeOffset.Parse(lastPivotItem.Tag as string);
if (selectedPivotItemDate.Date >= lastPivotItemDate.Date.AddDays(-3))
{
PivotItem pivotItem = new PivotItem();
DateTimeOffset date = new DateTimeOffset();
date = lastPivotItemDate.AddDays(1);
pivotItem.Tag = date.Month + "/" + date.Day + "/" + date.Year;
if (date.Date == DateTimeOffset.Now.Date)
{
pivotItem.Header = loader.GetString("Today");
}
else
{
pivotItem.Header = sdatefmt.Format(date).ToLower();
}
CalendarPivot.Items.Add(pivotItem);
}
PivotItem firstPivotItem = CalendarPivot.Items.First() as PivotItem;
DateTimeOffset firstPivotItemDate = new DateTimeOffset();
firstPivotItemDate = DateTimeOffset.Parse(firstPivotItem.Tag as string);
if (selectedPivotItemDate.Date <= firstPivotItemDate.Date.AddDays(3))
{
PivotItem pivotItem = new PivotItem();
DateTimeOffset date = new DateTimeOffset();
date = firstPivotItemDate.AddDays(-1);
pivotItem.Tag = date.Month + "/" + date.Day + "/" + date.Year;
if (date.Date == DateTimeOffset.Now.Date)
{
pivotItem.Header = "dziś";
}
else
{
pivotItem.Header = sdatefmt.Format(date).ToLower();
}
CalendarPivot.Items.Insert(0, pivotItem);
}
}
Debug.WriteLine("change ended" + CalendarPivot.SelectedIndex);
}
private void TodayAppBarButton_Click(object sender, RoutedEventArgs e)
{
pivotClear = true;
CalendarPivot.Items.Clear();
SetCalendar(DateTimeOffset.Now);
pivotClear = false;
}
private void ChooseDateAppBarButton_Click(object sender, RoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}
private void DatePickerFlyout_DatePicked(DatePickerFlyout sender, DatePickedEventArgs args)
{
pivotClear = true;
DateTimeOffset date = args.NewDate;
CalendarPivot.Items.Clear();
SetCalendar(date);
pivotClear = false;
}
}
}
It works well when I change days forward, but I have one heavyweight bug in backward way. I will try to explain it in steps.
Today is monday and user changes it to previous day.
Pivot's selected item changes from 4(monday) to 3(sunday) .
System decects that it must generate one more item to pivot.
System generates new item and inserts it in 0 position.
Pivot's selected item changes from 3 to 4(now sunday).
Pivot still shows item 3 which is saturday now, and it's looks like calendar skipped one day.
I would be very grateful if someone knows how to fix it.
EDIT :
I made change based on Nate Diamond suggestion and it works for now well:
Here, have a code:
XAML:
<Page
x:Class="LetsMakeANewCalendar.NewCalendar"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LetsMakeANewCalendar"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Pivot x:Name="CalendarPivot" Title="" SelectionChanged="CalendarPivot_SelectionChanged">
<PivotItem x:Name="PivotItem0"/>
<PivotItem x:Name="PivotItem1"/>
<PivotItem x:Name="PivotItem2"/>
<PivotItem x:Name="PivotItem3"/>
<PivotItem x:Name="PivotItem4"/>
<PivotItem x:Name="PivotItem5"/>
<PivotItem x:Name="PivotItem6"/>
</Pivot>
</Grid>
<Page.BottomAppBar>
<CommandBar>
<AppBarButton x:Name="TodayAppBarButton" Label="dziś" Click="TodayAppBarButton_Click">
<AppBarButton.Icon>
<FontIcon x:Name="TodayFontIcon" Glyph="" FontSize="10" FontFamily="Segoe WP"/>
</AppBarButton.Icon>
</AppBarButton>
<AppBarButton x:Name="ChooseDateAppBarButton" Label="wybierz" Icon="Calendar" Click="ChooseDateAppBarButton_Click">
<FlyoutBase.AttachedFlyout>
<DatePickerFlyout DatePicked="DatePickerFlyout_DatePicked"/>
</FlyoutBase.AttachedFlyout>
</AppBarButton>
</CommandBar>
</Page.BottomAppBar>
C#:
public sealed partial class NewCalendar : Page
{
int pivotIndex;
DateTimeOffset previousDate = new DateTimeOffset();
public NewCalendar()
{
this.InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
var monthDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("month.abbreviated");
SetCalendar(DateTimeOffset.Now);
TodayFontIcon.Glyph = DateTimeOffset.Now.Day + " " + monthDatefmt.Format(DateTimeOffset.Now);
}
private void SetCalendar(DateTimeOffset startDate)
{
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
var dayOfWeekDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("dayofweek.full");
var dayMonthYearDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("day month year");
int numberOfDay = GetNumberOfDay(startDate);
int i = 0;
foreach (PivotItem item in CalendarPivot.Items)
{
DateTimeOffset date = new DateTimeOffset();
date = startDate.AddDays(i - numberOfDay);
item.Tag = date.Month + "/" + date.Day + "/" + date.Year;
item.Header = dayOfWeekDatefmt.Format(date).ToLower();
i++;
}
CalendarPivot.SelectedIndex = pivotIndex = numberOfDay;
}
private int GetNumberOfDay(DateTimeOffset date)
{
int numberOfDay;
switch (date.DayOfWeek)
{
case DayOfWeek.Monday:
numberOfDay = 0;
break;
case DayOfWeek.Tuesday:
numberOfDay = 1;
break;
case DayOfWeek.Wednesday:
numberOfDay = 2;
break;
case DayOfWeek.Thursday:
numberOfDay = 3;
break;
case DayOfWeek.Friday:
numberOfDay = 4;
break;
case DayOfWeek.Saturday:
numberOfDay = 5;
break;
case DayOfWeek.Sunday:
numberOfDay = 6;
break;
default:
numberOfDay = -1;
break;
}
return numberOfDay;
}
private void CalendarPivot_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
Debug.WriteLine("old pivot index " + pivotIndex);
Debug.WriteLine("change started " + CalendarPivot.SelectedIndex);
var dayMonthYearDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("day month year");
if ((CalendarPivot.SelectedIndex == 6) && (pivotIndex == 0))
{
SetCalendar(previousDate.AddDays(-1));
}
else if ((CalendarPivot.SelectedIndex == 0) && (pivotIndex == 6))
{
SetCalendar(previousDate.AddDays(1));
}
PivotItem selectedPivotItem = CalendarPivot.SelectedItem as PivotItem;
DateTimeOffset selectedPivotItemDate = new DateTimeOffset();
selectedPivotItemDate = DateTimeOffset.Parse(selectedPivotItem.Tag as string);
previousDate = selectedPivotItemDate.Date;
pivotIndex = CalendarPivot.SelectedIndex;
CalendarPivot.Title = dayMonthYearDatefmt.Format(selectedPivotItemDate).ToUpper();
if (selectedPivotItemDate.Date == DateTimeOffset.Now.Date)
{
CalendarPivot.Title += " - " + loader.GetString("Today").ToUpper();
}
Debug.WriteLine("change ended " + CalendarPivot.SelectedIndex);
Debug.WriteLine("new pivot index " + pivotIndex);
}
private void TodayAppBarButton_Click(object sender, RoutedEventArgs e)
{
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
var dayMonthYearDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("day month year");
SetCalendar(DateTimeOffset.Now);
PivotItem selectedPivotItem = CalendarPivot.SelectedItem as PivotItem;
DateTimeOffset selectedPivotItemDate = new DateTimeOffset();
selectedPivotItemDate = DateTimeOffset.Parse(selectedPivotItem.Tag as string);
previousDate = selectedPivotItemDate.Date;
pivotIndex = CalendarPivot.SelectedIndex;
CalendarPivot.Title = dayMonthYearDatefmt.Format(selectedPivotItemDate).ToUpper() + " - " + loader.GetString("Today").ToUpper();
}
private void ChooseDateAppBarButton_Click(object sender, RoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout((FrameworkElement)sender);
}
private void DatePickerFlyout_DatePicked(DatePickerFlyout sender, DatePickedEventArgs args)
{
var loader = new Windows.ApplicationModel.Resources.ResourceLoader();
var dayMonthYearDatefmt = new Windows.Globalization.DateTimeFormatting.DateTimeFormatter("day month year");
DateTimeOffset date = args.NewDate;
SetCalendar(date);
PivotItem selectedPivotItem = CalendarPivot.SelectedItem as PivotItem;
DateTimeOffset selectedPivotItemDate = new DateTimeOffset();
selectedPivotItemDate = DateTimeOffset.Parse(selectedPivotItem.Tag as string);
previousDate = selectedPivotItemDate.Date;
pivotIndex = CalendarPivot.SelectedIndex;
CalendarPivot.Title = dayMonthYearDatefmt.Format(selectedPivotItemDate).ToUpper();
if (selectedPivotItemDate.Date == DateTimeOffset.Now.Date)
{
CalendarPivot.Title += " - " + loader.GetString("Today").ToUpper();
}
}
}

Access to controls inside a FlipView un XAML

In my Windows 8 app, I am trying to change the text of a textblock inside a DataTemplate of a FlipView...
my FlipView datatemplate (simplified...) :
<FlipView.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="test" />
</DataTemplate>
</FlipView.ItemTemplate>
I tried this solution : How do I access a control inside a XAML DataTemplate?
So my .cs :
var _Container = flipView.ItemContainerGenerator.ContainerFromItem(flipView.SelectedItem);
var _Children = AllChildren(_Container);
var myTextBlock= _Children.OfType<TextBlock>().FirstOrDefault(c => c.Name.Equals("test"));
myTextBlock.Text = "test";
with the method :
public List<Control> AllChildren(DependencyObject parent)
{
var _List = new List<Control>();
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var _Child = VisualTreeHelper.GetChild(parent, i);
if (_Child is Control)
_List.Add(_Child as Control);
_List.AddRange(AllChildren(_Child));
}
return _List;
}
But I get a NullReferenceException error : "{"Object reference not set to an instance of an object."}"
So it doesn't find my textblock...
Thanks
hello friend i have checked your code..and what i found is a very unnoticeable mistake..that is about the Control keyword..actually it is your type of control you want to search in your flipview..like textblock,textbox etc...you have to just change your AllChilderen Function like this and then all will work fine..
public List<TextBlock> AllChildren(DependencyObject parent)
{
var _List = new List<TextBlock>();
int j = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
{
var _Child = VisualTreeHelper.GetChild(parent, i);
if (_Child is TextBlock)
_List.Add(_Child as TextBlock);
_List.AddRange(AllChildren(_Child));
}
return _List;
}
hope it will help you..

Silverlight 4: Need help with Iteration

I'm having trouble with thinking of a solution that I'm trying to build, maybe someone here is able to guide me to the right direction.
I have a list of processes that belong to a processflow, these processes might have childs, and these childs might also have childs and so on.
The list looks like this:
ProcID ChildOFID
1 0 (means no child)
2 1
3 2
4 3
5 3
6 5
As you can see Proc "3" contains 2 childs, of which one (5) also has a child (6).
I want to iterate over this list and draw objects for them on a canvas.
Right now I have the following code but it requires me to write up a loop for every level that I want to show.
int prev_location_left = 0;
int prev_location_top = 0;
// Select Last ProcessStep (has no PreID!)
var lastProcess = (from p in processlist
where p.PreID == 0
select p).FirstOrDefault<ProcessStep>();
if (lastProcess != null)
{
create_processStep(lastProcess.ProcessID,
lastProcess.Name,
lastProcess.ProcessTypeID,
(900),
(30),
lastProcess.CummulativeCT,
lastProcess.WaitingTimeActual,
lastProcess.ValueAddTimeActual,
lastProcess.ProcessStepTime);
prev_location_left = 900;
prev_location_top = 30;
}
// Select all the ProcessSteps that are a child of the last(first) one.
var listChilds = (from p in processlist
where p.PreID == lastProcess.ProcessID
select p);
int childscount = listChilds.Count();
int cnt = 0;
foreach (ProcessStep ps in listChilds)
{
create_processStep(ps.ProcessID,
ps.Name,
ps.ProcessTypeID,
(prev_location_left - (150) ),
(30 + (60 *cnt)),
ps.CummulativeCT,
ps.WaitingTimeActual,
ps.ValueAddTimeActual,
ps.ProcessStepTime);
var listChilds2 = (from p in processlist
where p.PreID == ps.ProcessID
select p);
int cnt2 = 0;
foreach (ProcessStep ps2 in listChilds2)
{
create_processStep(ps2.ProcessID,
ps2.Name,
ps2.ProcessTypeID,
(prev_location_left - (300) ),
(30 + (60 *cnt2)),
ps2.CummulativeCT,
ps2.WaitingTimeActual,
ps2.ValueAddTimeActual,
ps2.ProcessStepTime);
var listChilds3 = (from p in processlist
where p.PreID == ps2.ProcessID
select p);
int cnt3 = 0;
foreach (ProcessStep ps3 in listChilds3)
{
create_processStep(ps3.ProcessID,
ps3.Name,
ps3.ProcessTypeID,
(prev_location_left - (450)),
(30 + (60 * cnt2)),
ps3.CummulativeCT,
ps3.WaitingTimeActual,
ps3.ValueAddTimeActual,
ps3.ProcessStepTime);
cnt3 = cnt3 + 1;
}
cnt2 = cnt2 + 1;
}
cnt = cnt + 1;
}
So what needs to be done is the following:
Get last process (the one with PreId == 0)
Check what his childs are and draw them on canvas: Left -150, first child on Top 30, Second on Top 90, Third on Top 150 and so on.
Now for every child found I also need to check if they have childs and do the same logic again, i'm having trouble making this a sort-endless loop.
Help! :)
You could create a recursive parent/child object and bind to it with your view. Below is a very basic example using the data that you've provided.
MainPage.xaml
<UserControl x:Class="SilverlightApplication4.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:SilverlightApplication4"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<local:MainPage_ViewModel/>
</UserControl.DataContext>
<Canvas>
<local:RecursiveView DataContext="{Binding RecursiveObject}"/>
</Canvas>
MainPage_ViewModel.cs
public class MainPage_ViewModel
{
public MainPage_ViewModel()
{
List<KeyValuePair<int, int>> collection = new List<KeyValuePair<int, int>>()
{
new KeyValuePair<int,int>(1,0),
new KeyValuePair<int,int>(2,1),
new KeyValuePair<int,int>(3,2),
new KeyValuePair<int,int>(4,3),
new KeyValuePair<int,int>(5,3),
new KeyValuePair<int,int>(6,5)
};
KeyValuePair<int, int> parent = collection.Where(kvp => kvp.Value == 0).First();
collection.Remove(parent);
RecursiveObject recursiveObject = new RecursiveObject()
{
root = parent.Key
};
populateChildren(recursiveObject, collection);
this.RecursiveObject = recursiveObject;
}
public RecursiveObject RecursiveObject
{
get { return recursiveObject; }
set { recursiveObject = value; }
}
private RecursiveObject recursiveObject;
private void populateChildren(RecursiveObject parent, List<KeyValuePair<int, int>> list)
{
List<KeyValuePair<int, int>> children = list.Where(kvp => kvp.Value == parent.root).ToList();
children.ForEach(child => list.Remove(child));
children.ForEach(child =>
{
RecursiveObject newChild = new RecursiveObject() { root = child.Key };
parent.Children.Add(newChild);
populateChildren(newChild, list);
});
}
}
RecursiveObject.cs
public class RecursiveObject
{
public int root { get; set; }
public List<RecursiveObject> Children
{
get { return children; }
set { children = value; }
}
private List<RecursiveObject> children = new List<RecursiveObject>();
}
RecursiveView.xaml
<UserControl x:Class="SilverlightApplication4.RecursiveView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:local="clr-namespace:SilverlightApplication4"
d:DesignHeight="300" d:DesignWidth="400">
<StackPanel Margin="30,0,0,0">
<TextBlock Text="{Binding root}"/>
<ItemsControl ItemsSource="{Binding Children}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:RecursiveView DataContext="{Binding}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
Image of output:
I just placed a margin of '30' on the left of each child, but you could adjust it to be whatever you'd like. Not sure if this helps, I just thought it was a fun challenge to try :)

Character Casing in Silverlight 4 TextBox

I am writing a Silverlight 4 business application and have run into an issue. I need the text input in TextBoxes to be forced to UpperCase. What I understand from various forums is Silverlight does not Implement CharacterCasing and CSS Styling.
Is there any other way to achieve this?
You can achieve this by creating a behavior, like this:
public class UpperCaseAction : TriggerAction<TextBox>
{
protected override void Invoke(object parameter)
{
var selectionStart = AssociatedObject.SelectionStart;
var selectionLenght = AssociatedObject.SelectionLength;
AssociatedObject.Text = AssociatedObject.Text.ToUpper();
AssociatedObject.SelectionStart = selectionStart;
AssociatedObject.SelectionLength = selectionLenght;
}
}
Then, use it in your TextBox, like this:
<Grid x:Name="LayoutRoot" Background="White">
<TextBox TextWrapping="Wrap" VerticalAlignment="Top" Margin="10">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<ASD_Answer009_Behaviors:UpperCaseAction/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</Grid>
Where i: is a namespace for
clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity
Code behind:
System.Windows.Interactivity.EventTrigger eventTrigger = new System.Windows.Interactivity.EventTrigger("TextChanged");
eventTrigger.Actions.Add(new UpperCaseAction());
System.Windows.Interactivity.Interaction.GetTriggers(myTextBox).Add(eventTrigger);
In order to create and use behaviors, you need to download and install the Expression Blend SDK for Silverlight 4 and add a reference to System.Windows.Interactivity.dll.
Try this:
private void txt2_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = MakeUpperCase((TextBox)sender, e);
}
bool MakeUpperCase(TextBox txt, KeyEventArgs e)
{
if (Keyboard.Modifiers != ModifierKeys.None || (e.Key < Key.A) || (e.Key > Key.Z)) //do not handle ModifierKeys (work for shift key)
{
return false;
}
else
{
string n = new string(new char[] { (char)e.PlatformKeyCode });
int nSelStart = txt.SelectionStart;
txt.Text = txt.Text.Remove(nSelStart, txt.SelectionLength); //remove character from the start to end selection
txt.Text = txt.Text.Insert(nSelStart, n); //insert value n
txt.Select(nSelStart + 1, 0); //for cursortext
return true; //stop to write in txt2
}
}
private void txt2_KeyDown(object sender, KeyEventArgs e)
{
if (Keyboard.Modifiers != ModifierKeys.None) return; //do not handle ModifierKeys (work for shift key)
string n = new string(new char[] { (char)e.PlatformKeyCode });
int nSelStart = txt2.SelectionStart;
txt2.Text = txt2.Text.Remove(nSelStart, txt2.SelectionLength); //remove character from the start to end selection
txt2.Text = txt2.Text.Insert(nSelStart, n); //insert value n
txt2.Select(nSelStart + 1, 0); //for cursortext
e.Handled = true; //stop to write in txt2
}