I want to create a page with dynamic control in windows phone.
While doing this I also want to show a progress bar
Below is my code
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
progressstackPanel.Visibility = Visibility.Visible;//progress bar
formScreen = this;
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
if (!isfst)
{
DrawScreen();
}
else
{
//xTitlePanel is only stack panel in my xaml with vertical orientation
xTitlePanel.UpdateLayout();
}
isfst = true;
progressstackPanel.Visibility = Visibility.Collapsed;
});
}
//Code of DrawScreen which is adding control to my stack panels
private void DrawScreen()
{
if (frm_getset.ChildList != null)
{
String[] arr = frm_getset.ChildList.Split(',');
xTitlePanel.Children.Clear();
PrepareControls prepcontrol = new PrepareControls();
foreach (AttributeGetSet a in _Attribute)
{
//this will return a stackpanel containing
// button/textbox etc.depending on a
StackPanel sp = prepcontrol.getControl(i, a.Label, a, formScreen);
try
{
xTitlePanel.Children.Add(sp);
///Here I get a eception only one control is added first one
/// for anyone it is getting a exception Argument
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
i += 1;
}
The system is adding only one control and when ever it try to execute xTitlePanel.Children.Add(sp); it will get an exception.
I solved the problem ,"xTitlePanel" is a StackPanel I created in my XAML. I found you can not add more that one element from Dispatcher to a control crated on xaml. Like that. so I have to create local stack and add controls to the that local stack panel then and after complete I add the local stack panel to xTitlePanel. NOW my code looks like below
filteredList = new List<FormGetSet>();
if (frm_getset.ChildList != null)
{
String[] arr = frm_getset.ChildList.Split(',');
foreach (String x in arr)
{
filteredList.Add(_template.list_fromgetset.Where(p => p.FormID.Contains(x.Trim())).ToList()[0]);
}
}
xTbox_FormNameHeader.Text = frm_getset.NAME;
_Attribute = new List<AttributeGetSet>();
_Attribute = frm_getset.list_attributegetset;
xTitlePanel.Children.Clear();
StackPanel spPanel = new StackPanel();
spPanel.Orientation = System.Windows.Controls.Orientation.Vertical;
spPanel.Background = new SolidColorBrush(Colors.Transparent);
//xTitlePanel.Children.Add(PrepareControls.getControl(1, "LABEL", "16"));
int i = 1;
// List<AttributeGetSet> _Attribute2 = new List<AttributeGetSet>();
foreach (AttributeGetSet a in _Attribute)
{
PrepareControls prepcontrol = new PrepareControls();
StackPanel sp= prepcontrol.getControl(i, a.Label, a, this);
try
{
spPanel.Children.Add(sp);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
//xTitlePanel.Background = new SolidColorBrush(Colors.White);
//_Attribute2.Add(a);
i += 1;
}
xTitlePanel.Children.Add(spPanel);
Related
I am reading a list of files in a folder in my Xamarin app and displaying them in a ListView. On Android, the files are created and read in the correct order, but on iOS, they are created in the right order, but read and displayed in a weird order and in the exact same weird order every time. I know it's not a problem with the ListView because I was using Syncfusion's SfListView recently and had the same problem with that. Why is it like this?
The correct order of the files:
What they look like on iOS:
My code to create the files:
using Partylist.Models;
using System;
using System.IO;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Partylist.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class NewEventPage : ContentPage
{
...
// Event handler for when the "Create" button gets clicked.
async void OnCreateClicked(object sender, EventArgs e)
{
// Make sure there is something in the text entry.
if (string.IsNullOrWhiteSpace(EventNameEntry.Text))
{
// If there is nothing there, display an error message.
await DisplayAlert("Oops!", "Your event needs a name!",
"OK");
}
// If there is something in the text entry, try to create
// a new event with the text as its name.
else
{
// Variable to store the created event.
Event newEvent = new Event();
// Variable to store its folder.
DirectoryInfo newEventFolder;
// Flag to see if the event was created sccessfully.
bool eventCreated;
try
{
// If there's already an event with that name, let the
// user know.
if (Directory.Exists(Path.Combine(App.eventFolderPath,
EventNameEntry.Text)))
{
await DisplayAlert("Oops!", "You already have an event with that name.", "Ok");
eventCreated = false;
}
// Otherwise, try to create the folder.
else
{
newEventFolder = Directory.CreateDirectory(
Path.Combine(App.eventFolderPath,
EventNameEntry.Text));
// Then, create the event based on that folder.
newEvent = new Event
{
EventFolder = newEventFolder,
Location = WhereEntry.Text,
EventDate = EventDatePicker.Date,
StartTime = EventStartTimePicker.Time,
EndTime = EventEndTimePicker.Time,
Refreshments = RefreshmentsEntry.Text,
Activities = ActivitiesEntry.Text,
NumGuests = NumGuestsEntry.Text,
Theme = ThemeEntry.Text,
Budget = BudgetEntry.Text,
WillThereBePartyFavors = PartyFavorsEntry.Text,
ShouldGuestsBringGifts = GiftsEntry.Text,
WillThereBeChildren = ChildrenEntry.Text
};
// --- Add several premade lists to the event (all of --- //
// --- which are empty except the main checklist) --- //
// First, the main checklist. Also, set it as such.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Main Checklist.mchec"))) { }
// Then, a contact list for important phone numbers.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Important Phone Numbers.cont"))) { }
// And another contact list for guests.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Guests.cont"))) { }
// The next thing we need is a schedule of activities.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Schedule of Activities.sched"))) { }
// After that, a checklist for things to do.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Things to Do.chec"))) { }
// And one for things to gather.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Things to Gather.chec"))) { }
// And one for things to buy.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Things to Buy.chec"))) { }
// And one for things to make.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Things to Make.chec"))) { }
// And one that serves as a grocery list.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"Groceries.chec"))) { }
// There will also be one for things to do the day before the event.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"The Day Before.chec"))) { }
// And one for things to do the day of.
using (FileStream fs = File.Create(Path.Combine(App
.eventFolderPath, EventNameEntry.Text,
"The Day Of.chec"))) { }
// --- End of adding pre-made lists --- //
// Let the program know that an event has been created.
eventCreated = true;
}
}
// Should throw an ArgumentException in most cases where there is
// an invalid character.
catch (ArgumentException)
{
// Get all the invalid characters and turn them into a string.
char[] invalidChars = Path.GetInvalidPathChars();
string invalid = "";
foreach(char currentChar in invalidChars)
{
invalid += currentChar;
}
// Display an error message.
await DisplayAlert("Oops!", "Your event name can't have these characters: \""
+ invalid + "\".", "Ok");
eventCreated = false;
}
// If the event was created successfully, start the tip
// timer, select the event, open a "List" page
// for it, and removed the "New Event" page.
if (eventCreated)
{
App.tipTimer.Start();
App.selectedEvent = newEvent;
await Navigation.PushAsync(new ListsPage());
Navigation.RemovePage(this);
}
}
}
}
}
And my code to read in the files:
using Partylist.Models;
using System;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Partylist.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ListsPage : ContentPage
{
// List of lists, used to populate
// the page's ListView (see the XAML).
public ObservableCollection<PartylistList> ListList { get; set; }
...
// Override for OnAppearing().
protected override void OnAppearing()
{
// Regular OnAppearing() method.
base.OnAppearing();
// Set the title to be the name of the selected event.
Title = App.selectedEvent.EventFolder.Name;
// Set the BindingContext of the page to itself.
BindingContext = this;
// Update the ListView.
UpdateListView();
...
}
// Function to update the ListView when the page loads or when something changes.
private void UpdateListView()
{
// Set the list of lists to a new ObservableCollection
// that we can add stuff to.
ListList = new ObservableCollection<PartylistList>();
// Loop to populate the ObservableCollection.
for (int i = 0; i < Directory.GetFiles(
Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))
.Length; i++)
{
// If the current file is the main checklist (filename ends with ".mchec"),
// then add it to the list of lists as the main checklist.
if (Directory.GetFiles(Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))[i].EndsWith(".mchec"))
{
ListList.Add(new PartylistList(new FileInfo(Path.GetFullPath(
Directory.GetFiles(Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))[i])), new ChecklistPage(),
"#FF7700", "master_checklist_icon.png"));
// Set a "Rename" button as this thing's only SwipeItem.
ListList.ElementAt(i).SwipeOptions.Add(new SwipeItem()
{
Text = "Rename",
BackgroundColor = Color.FromHex("#ff7700"),
CommandParameter = ListList.ElementAt(i)
});
ListList.ElementAt(i).SwipeOptions[0].Invoked += OnRename;
// Set this as the event's main checklist.
App.selectedEvent.MainChecklist = new FileInfo(Path.GetFullPath(
Directory.GetFiles(Path.Combine(App.eventFolderPath, App
.selectedEvent.EventFolder.Name))[i]));
}
// If the current file is a contact list (filename ends with ".cont"),
// then add it to the list of lists as a contact list.
else if (Directory.GetFiles(Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))[i].EndsWith(".cont"))
{
ListList.Add(new PartylistList(new FileInfo(Path.GetFullPath(
Directory.GetFiles(Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))[i])), new ContactsListPage(),
"#00DFDF", "contact_list_icon.png"));
// Set a "Delete" button as the first SwipeItem.
ListList.ElementAt(i).SwipeOptions.Add(new SwipeItem()
{
Text = "Delete",
BackgroundColor = Color.FromHex("#ff418b"),
CommandParameter = ListList.ElementAt(i)
});
ListList.ElementAt(i).SwipeOptions[0].Invoked += OnDelete;
// Set a "Rename" button as the second SwipeItem.
ListList.ElementAt(i).SwipeOptions.Add(new SwipeItem()
{
Text = "Rename",
BackgroundColor = Color.FromHex("#ff7700"),
CommandParameter = ListList.ElementAt(i)
});
ListList.ElementAt(i).SwipeOptions[1].Invoked += OnRename;
}
// Else if it is a schedule (filename ends with ".sched"), then
// add it to the list of lists as a schedule.
else if (Directory.GetFiles(Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))[i].EndsWith(".sched"))
{
ListList.Add(new PartylistList(new FileInfo(Path.GetFullPath(
Directory.GetFiles(Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))[i])), new SchedulePage(),
"#BB0099", "schedule_icon.png"));
// Set a "Delete" button as the first SwipeItem.
ListList.ElementAt(i).SwipeOptions.Add(new SwipeItem()
{
Text = "Delete",
BackgroundColor = Color.FromHex("#ff418b"),
CommandParameter = ListList.ElementAt(i)
});
ListList.ElementAt(i).SwipeOptions[0].Invoked += OnDelete;
// Set a "Rename" button as the second SwipeItem.
ListList.ElementAt(i).SwipeOptions.Add(new SwipeItem()
{
Text = "Rename",
BackgroundColor = Color.FromHex("#ff7700"),
CommandParameter = ListList.ElementAt(i)
});
ListList.ElementAt(i).SwipeOptions[1].Invoked += OnRename;
}
// Else if it is a checklist (filename ends with ".chec"), then
// add it to the list of lists as a checklist.
else if (Directory.GetFiles(Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))[i].EndsWith(".chec"))
{
ListList.Add(new PartylistList(new FileInfo(Path.GetFullPath(
Directory.GetFiles(Path.Combine(App.eventFolderPath,
App.selectedEvent.EventFolder.Name))[i])), new ChecklistPage(),
"#3F7FFF", "checklist_icon.png"));
// Set a "Delete" button as the first SwipeItem.
ListList.ElementAt(i).SwipeOptions.Add(new SwipeItem()
{
Text = "Delete",
BackgroundColor = Color.FromHex("#ff418b"),
CommandParameter = ListList.ElementAt(i)
});
ListList.ElementAt(i).SwipeOptions[0].Invoked += OnDelete;
// Set a "Rename" button as the second SwipeItem.
ListList.ElementAt(i).SwipeOptions.Add(new SwipeItem()
{
Text = "Rename",
BackgroundColor = Color.FromHex("#ff7700"),
CommandParameter = ListList.ElementAt(i)
});
ListList.ElementAt(i).SwipeOptions[1].Invoked += OnRename;
}
// Set the ItemsSource of the ListView in the XAML to the ObservableCollection.
ListListView.ItemsSource = ListList;
// Calls OnPropertyChanged() which makes the ListView update.
OnPropertyChanged("ListList");
}
}
...
}
}
How do I get the index or position where a GridViewItem is being dropped inside the OnDrop event of the GridView? As I have read around that it is possible with GridView.ItemContainerGenerator.ContainerFromItem(item) but for me ItemContainerGenerator is null.
This is my current code:
void gridMain_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
var item = e.Items.First();
var source = sender;
e.Data.Properties.Add("item", item);
e.Data.Properties.Add("source", sender);
}
void gridMain_Drop(object sender, DragEventArgs e)
{
var item = e.Data.Properties.Where(p => p.Key == "item").Single();
object source;
e.Data.Properties.TryGetValue("source", out source);
var s = ((GridView)source).ItemContainerGenerator.ContainerFromItem(item);
}
Any hint or suggestion will be really helpful.
Use GetPosition method of DragEventArgs to find the position where item was dropped and then calculate the actual index, see code snippet below for the handler. Similar question was asked here using this MSDN example as an answer (Scenario 3).
private void GridView_Drop(object sender, DragEventArgs e)
{
GridView view = sender as GridView;
// Get your data
var item = e.Data.Properties.Where(p => p.Key == "item").Single();
//Find the position where item will be dropped in the gridview
Point pos = e.GetPosition(view.ItemsPanelRoot);
//Get the size of one of the list items
GridViewItem gvi = (GridViewItem)view.ContainerFromIndex(0);
double itemHeight = gvi.ActualHeight + gvi.Margin.Top + gvi.Margin.Bottom;
//Determine the index of the item from the item position (assumed all items are the same size)
int index = Math.Min(view.Items.Count - 1, (int)(pos.Y / itemHeight));
// Call your viewmodel with the index and your data.
}
EDIT: Please, consider this as just a prototype. I tried it and it has worked properly, but you may revise it according to your scenario (tweak delay timeout, differentiate more TaskCompletionSource at once, etc.).
The idea is to start a task after Remove action to check whether the item was only removed, or reordered.
private async void observableCollection_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
{
object removedItem = e.OldItems[0];
var reorderTask = NoticeReorderAsync(removedItem);
try
{
var task = await Task.WhenAny(reorderTask, Task.Delay(100));
if (reorderTask == task)
{
// removedItem was in fact reordered
Debug.WriteLine("reordered");
}
else
{
TryCancelReorder();
// removedItem was really removed
Debug.WriteLine("removedItem");
}
}
catch (TaskCanceledException ex)
{
Debug.WriteLine("removedItem (from exception)");
}
finally
{
tcs = null;
}
}
else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
{
object addedItem = e.NewItems[0];
bool added = NoticeAdd(addedItem);
if (added)
{
// addedItem was just added, not reordered
Debug.WriteLine("added");
}
}
}
TaskCompletionSource<object> tcs;
private void TryCancelReorder()
{
if (tcs != null)
{
tcs.TrySetCanceled();
tcs = null;
}
}
private Task NoticeReorderAsync(object removed)
{
TryCancelReorder();
tcs = new TaskCompletionSource<object>(removed);
return tcs.Task;
}
private bool NoticeAdd(object added)
{
if (tcs != null)
{
try
{
if (object.Equals(tcs.Task.AsyncState, added))
{
tcs.TrySetResult(added);
return false;
}
else
{
tcs.TrySetCanceled();
return true;
}
}
finally
{
tcs = null;
}
}
return true;
}
I want to create Application Bar dynamically in Windows Phone 8. I have used the following code to create application bar in appbar.cs file
class AppBar
{
public AppBar()
{
ApplicationBar appbar;
this.appbar = new ApplicationBar();
this.appbar.IsVisible = true;
this.appbar.Opacity = 1;
this.appbar.Mode = ApplicationBarMode.Minimized;
ApplicationBarIconButton appButon = new ApplicationBarIconButton();
appButon.IconUri = new Uri("/images/show.png", UriKind.Relative);
appButon.Text = "Show";
this.appbar.Buttons.Add(appButon);
appButon.Click += appButon_Click;
}
}
void appButon_Click(object sender, EventArgs e)
{
}
}
If i have created the instance of AppBar class, then all the methods called but i unable to see the application bar. I have given request to create the appbar from webview. From the javainterface i have created the instance of application bar with the given text and icon. How to show this in the web page.
I have solved the my Application bar issue. Added my application bar with parent element(PhoneApplicationPage).
class AppBar
{
public AppBar()
{
ApplicationBar appbar;
PhoneApplicationPage parentpage = (Application.Current.RootVisual as ContentControl).Content as PhoneApplicationPage;
parentpage.ApplicationBar = new ApplicationBar();
appbar = parentpage.ApplicationBar;
appbar.IsVisible = true;
appbar.Opacity = 1;
appbar.Mode = ApplicationBarMode.Minimized;
ApplicationBarIconButton appButon = new ApplicationBarIconButton();
appButon.IconUri = new Uri("/images/show.png", UriKind.Relative);
appButon.Text = "Show";
appbar.Buttons.Add(appButon);
appButon.Click += appButon_Click;
}
}
void appButon_Click(object sender, EventArgs e)
{
}
}
How do I enter snap state using the Windows 8 emulator? I received a notice from the Windows 8 store that my software crashes in snap mode only. Does anyone know why switching modes would cause my software to crash? Here is my code behind:
namespace MenuFinderWin8.Pages
{
public sealed partial class RestaurantHomePage : MenuFinderWin8.Common.LayoutAwarePage
{
MenuFinderAppServiceClient serviceClient;
RestaurantRepository repository;
Geolocator _geolocator = null;
ObservableCollection<RestaurantLocation> items;
public RestaurantHomePage()
{
this.InitializeComponent();
if (!Network.IsNetwork())
{
return;
}
repository = new RestaurantRepository();
serviceClient = new MenuFinderAppServiceClient();
_geolocator = new Geolocator();
items = new ObservableCollection<RestaurantLocation>();
BindData();
}
void btnAbout_Click(object sender, RoutedEventArgs e)
{
Flyout f = new Flyout();
LayoutRoot.Children.Add(f.HostPopup); // add this to some existing control in your view like the root visual
// remove the parenting during the Closed event on the Flyout
f.Closed += (s, a) =>
{
LayoutRoot.Children.Remove(f.HostPopup);
};
// Flyout is a ContentControl so set your content within it.
SupportUserControl userControl = new SupportUserControl();
userControl.UserControlFrame = this.Frame;
f.Content = userControl;
f.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 223, 58, 51));
f.Width = 200;
f.Height = 200;
f.Placement = PlacementMode.Top;
f.PlacementTarget = sender as Button; // this is an UI element (usually the sender)
f.IsOpen = true;
}
void btnSearch_Click(object sender, RoutedEventArgs e)
{
Flyout f = new Flyout();
LayoutRoot.Children.Add(f.HostPopup); // add this to some existing control in your view like the root visual
// remove the parenting during the Closed event on the Flyout
f.Closed += (s, a) =>
{
LayoutRoot.Children.Remove(f.HostPopup);
};
// Flyout is a ContentControl so set your content within it.
RestaurantSearchUserControl userControl = new RestaurantSearchUserControl();
userControl.UserControlFrame = this.Frame;
f.Content = userControl;
f.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 223, 58, 51));
f.Width = 600;
f.Height = 400;
f.Placement = PlacementMode.Top;
f.PlacementTarget = sender as Button; // this is an UI element (usually the sender)
f.IsOpen = true;
}
void btnViewFavorites_Click(object sender, RoutedEventArgs e)
{
App.DataMode = Mode.SavedRestaurant;
if (repository.GetGroupedRestaurantsFromDatabase().Count() == 0)
{
MessageDialog messageDialog = new MessageDialog("You have no saved restaurants.", "No Restaurants");
messageDialog.ShowAsync();
}
else
{
this.Frame.Navigate(typeof(RestaurantSearchDetails));
}
}
private async void BindData()
{
try
{
items = await serviceClient.GetSpecialRestaurantsAsync();
List<RestaurantLocation> myFavs = repository.GetRestaurantLocations();
foreach (var a in myFavs)
{
items.Add(a);
}
this.DefaultViewModel["Items"] = items;
}
catch (Exception)
{
MessageDialog messsageDialog = new MessageDialog("The MenuFinder service is unavailable at this time or you have lost your internet connection. If your internet is OK, please check back later.", "Unavailable");
messsageDialog.ShowAsync();
btnAbout.IsEnabled = false;
btnSearch.IsEnabled = false;
btnViewFavorites.IsEnabled = false;
}
myBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
/// provided when recreating a page from a prior session.
/// </summary>
/// <param name="navigationParameter">The parameter value passed to
/// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
/// </param>
/// <param name="pageState">A dictionary of state preserved by this page during an earlier
/// session. This will be null the first time a page is visited.</param>
protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
// TODO: Assign a bindable collection of items to this.DefaultViewModel["Items"]
}
private void itemGridView_ItemClick_1(object sender, ItemClickEventArgs e)
{
App.CurrentRestaurantLocation = e.ClickedItem as RestaurantLocation;
if (App.CurrentRestaurantLocation != null)
{
Order order = repository.AddOrder(DateTime.Now, string.Empty, App.CurrentRestaurantLocation.ID);
App.CurrentOrder = order;
App.DataMode = Mode.Menu;
this.Frame.Navigate(typeof(RootViewPage));
}
}
}
}
In response to "How do I enter snap state using the Windows 8 emulator?" - I find the easiest way to snap in the simulator is to use the keyboard shortcut, which is Windows key + . (period).
The error might be in your XAML, more than in the code behind. If you used a template but deleted or modified the name in one of the elements, the KeyFrame refering to that element is failing getting the element, so an exception is thrown.
Search in your XAML for something like
<VisualState x:Name="Snapped">
<Storyboard>...
And delete the ObjectAnimationUsingKeyFrames tags which Storyboard.TargetName property is equal to a non-existant element.
Refering on how to enter Snapped Mode on the emulator, is the same as in PC, just grab the App from the top and slide it to a side while holding the click.
Using a GridView, I bind to several items in an observable collection. When I enter snapped mode, my GridView fails to load any data and none of the items are clickable. See attached screenshot. My app is on the left and it says featured and favorites. Here is my code:
public sealed partial class RestaurantHomePage : MenuFinderWin8.Common.LayoutAwarePage
{
MenuFinderAppServiceClient serviceClient;
RestaurantRepository repository;
Geolocator _geolocator = null;
ObservableCollection<RestaurantLocation> items;
public RestaurantHomePage()
{
this.InitializeComponent();
if (!Network.IsNetwork())
{
return;
}
repository = new RestaurantRepository();
serviceClient = new MenuFinderAppServiceClient();
_geolocator = new Geolocator();
items = new ObservableCollection<RestaurantLocation>();
//BindData();
}
void btnAbout_Click(object sender, RoutedEventArgs e)
{
Flyout f = new Flyout();
LayoutRoot.Children.Add(f.HostPopup); // add this to some existing control in your view like the root visual
// remove the parenting during the Closed event on the Flyout
f.Closed += (s, a) =>
{
LayoutRoot.Children.Remove(f.HostPopup);
};
// Flyout is a ContentControl so set your content within it.
SupportUserControl userControl = new SupportUserControl();
userControl.UserControlFrame = this.Frame;
f.Content = userControl;
f.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 223, 58, 51));
f.Width = 200;
f.Height = 200;
f.Placement = PlacementMode.Top;
f.PlacementTarget = sender as Button; // this is an UI element (usually the sender)
f.IsOpen = true;
}
void btnSearch_Click(object sender, RoutedEventArgs e)
{
Flyout f = new Flyout();
LayoutRoot.Children.Add(f.HostPopup); // add this to some existing control in your view like the root visual
// remove the parenting during the Closed event on the Flyout
f.Closed += (s, a) =>
{
LayoutRoot.Children.Remove(f.HostPopup);
};
// Flyout is a ContentControl so set your content within it.
RestaurantSearchUserControl userControl = new RestaurantSearchUserControl();
userControl.UserControlFrame = this.Frame;
f.Content = userControl;
f.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(255, 223, 58, 51));
f.Width = 600;
f.Height = 400;
f.Placement = PlacementMode.Top;
f.PlacementTarget = sender as Button; // this is an UI element (usually the sender)
f.IsOpen = true;
}
void btnViewFavorites_Click(object sender, RoutedEventArgs e)
{
App.DataMode = Mode.SavedRestaurant;
if (repository.GetGroupedRestaurantsFromDatabase().Count() == 0)
{
MessageDialog messageDialog = new MessageDialog("You have no saved restaurants.", "No Restaurants");
messageDialog.ShowAsync();
}
else
{
this.Frame.Navigate(typeof(RestaurantSearchDetails));
}
}
private async void BindData()
{
try
{
items = await serviceClient.GetSpecialRestaurantsAsync();
List<RestaurantLocation> myFavs = repository.GetRestaurantLocations();
foreach (var a in myFavs)
{
items.Add(a);
}
this.DefaultViewModel["Items"] = items;
}
catch (Exception)
{
MessageDialog messsageDialog = new MessageDialog("The MenuFinder service is unavailable at this time or you have lost your internet connection. If your internet is OK, please check back later.", "Unavailable");
messsageDialog.ShowAsync();
btnAbout.IsEnabled = false;
btnSearch.IsEnabled = false;
btnViewFavorites.IsEnabled = false;
}
myBar.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
/// <summary>
/// Populates the page with content passed during navigation. Any saved state is also
/// provided when recreating a page from a prior session.
/// </summary>
/// <param name="navigationParameter">The parameter value passed to
/// <see cref="Frame.Navigate(Type, Object)"/> when this page was initially requested.
/// </param>
/// <param name="pageState">A dictionary of state preserved by this page during an earlier
/// session. This will be null the first time a page is visited.</param>
protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
{
BindData();
// TODO: Assign a bindable collection of items to this.DefaultViewModel["Items"]
}
private void itemGridView_ItemClick_1(object sender, ItemClickEventArgs e)
{
App.CurrentRestaurantLocation = e.ClickedItem as RestaurantLocation;
if (App.CurrentRestaurantLocation != null)
{
Order order = repository.AddOrder(DateTime.Now, string.Empty, App.CurrentRestaurantLocation.ID);
App.CurrentOrder = order;
App.DataMode = Mode.Menu;
this.Frame.Navigate(typeof(RootViewPage));
}
}
}
When you switch to snapped view, your gridView hides, and a ListView shows up. You can see this by checking the Visual State Manager that handles going from one to another in your XAML.
So, Solution is: adapting the ItemTemplate from your ListView as you did with your GridView by Binding to the proper attributes; you may also want to change the Foreground color of your Font. Also, you want to include the IsItemClickEnabled and ItemClick (or SelectionMode and SelectionChanged) on your ListView.