SharePoint issue with Eventhandler - sharepoint-2010

PROBLEM: I have a list and if I create a new Item I would like to do the following:
Create a new AutoIncrement Number in Column [AutoGeneratedID]
Use [Titel] and [AutoGeneratedID] to create a HyperLink in the List and a new subsite
The problem is i cant get the [AutogeneratedID] filled with a value because it is an itemadded event but if i try to put the code together in an ItemAdding event, i get a problem as described in the following link:
http://www.sharepoint-tips.com/2006/09/synchronous-add-list-event-itemadding.html
using System;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.Workflow;
using System.Diagnostics;
namespace KuC_Solution.EventReceiver1
{
/// <summary>
/// List Item Events
/// </summary>
public class EventReceiver1 : SPItemEventReceiver
{
/// <summary>
/// An item was added.
/// </summary>
public override void ItemAdded(SPItemEventProperties properties)
{
base.ItemAdded(properties);
// -----------------------------------------------------------
try
{
this.EventFiringEnabled = false;
// Column name AutoGeneratedID
string columnName = "AutoGeneratedID";
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPWeb web = properties.OpenWeb())
{
web.AllowUnsafeUpdates = true;
//get the current list
SPList list = web.Lists[properties.ListId];
int highestValue = 0;
foreach (SPListItem item in list.Items)
{
if (item[columnName] != null && item[columnName].ToString().Trim() != "")
{
string value = item[columnName].ToString();
try
{
int currValue = int.Parse(value);
if (currValue > highestValue)
highestValue = currValue;
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
}
}
SPListItem currItem = list.Items.GetItemById(properties.ListItem.ID);
currItem[columnName] = (highestValue + 1).ToString();
currItem.SystemUpdate(false);
web.AllowUnsafeUpdates = false;
}
});
this.EventFiringEnabled = true;
}
catch (Exception ex)
{
Trace.WriteLine(ex.Message);
}
// -----------------------------------------------------------
}
/// <summary>
/// An item is being added.
/// </summary>
public override void ItemAdding(SPItemEventProperties properties)
{
base.ItemAdding(properties);
//-------------------------------------------------------------
// Get the web where the event was raised
SPWeb spCurrentSite = properties.OpenWeb();
//Get the name of the list where the event was raised
String curListName = properties.ListTitle;
//If the list is our list named SubSites the create a new subsite directly below the current site
if (curListName == "TESTautoNumber")
{
//Get the SPListItem object that raised the event
SPListItem curItem = properties.ListItem;
//Get the Title field from this item. This will be the name of our new subsite
String curItemSiteName2 = properties.AfterProperties["Title"].ToString();
//String curItemSiteName3 = properties.AfterProperties["ID"].ToString();
String mia = properties.AfterProperties["AutoGeneratedID"].ToString();
String curItemSiteName = curItemSiteName2 + mia;
//Get the Description field from this item. This will be the description for our new subsite
//String curItemDescription = properties.AfterProperties["Projekt-ID"].ToString();
string curItemDescription = "CREWPOINT";
//String testme = "1";
//Update the SiteUrl field of the item, this is the URL of our new subsite
properties.AfterProperties["tLINK"] = spCurrentSite.Url + "/" + curItemSiteName;
//Create the subsite based on the template from the Solution Gallery
SPWeb newSite = spCurrentSite.Webs.Add(curItemSiteName, curItemSiteName, curItemDescription, Convert.ToUInt16(1033), "{4ADAD620-701D-401E-8DBA-B4772818E270}#myTemplate2012", false, false);
//Set the new subsite to inherit it's top navigation from the parent site, Usefalse if you do not want this.
newSite.Navigation.UseShared = true;
newSite.Close();
}
//---------------------------------------------------------------
}
}
}

Related

ABP: How to re- load Localization text dynamically without restarting API app

I am using ABP v4.7.0 (.NET CORE 2.1) with angular client.
I built some custom localization providers. These providers get translation dictionaries from Azure Blob Storage. I add localization sources on startup with these providers.
localizationConfiguration.Sources.Add(
new DictionaryBasedLocalizationSource(InductothermMVPConsts.LocalizationSourceName,
new BlobEmbeddedFileLocalizationDictionaryProvider(
typeof(InductothermMVPLocalizationConfigurer).GetAssembly(),
"InductothermMVP.Core.Localization.SourceFiles"
)
)
);
On StartUp, I call this method and localization dictionaries are built correctly.
Now, I created one api endpoint which will update data in Azure Blob Storage, after files are updated, I am again initializing the dictionaries
public class BlobEmbeddedFileLocalizationDictionaryProvider : LocalizationDictionaryProviderBase
{
#pragma warning disable GCop406 // Mark {0} field as read-only.
private const int Count = 50;
#pragma warning restore GCop406 // Mark {0} field as read-only.
private readonly Assembly _assembly;
private readonly string _rootNamespace;
/// <summary>
/// Creates a new <see cref="BlobEmbeddedFileLocalizationDictionaryProvider"/> object.
/// </summary>
/// <param name="assembly">Assembly that contains embedded xml files</param>
/// <param name="rootNamespace">Namespace of the embedded xml dictionary files</param>
public BlobEmbeddedFileLocalizationDictionaryProvider(Assembly assembly, string rootNamespace)
{
_assembly = assembly;
_rootNamespace = rootNamespace;
InitializeDictionaries();
}
protected void InitializeDictionaries()
{
var sourceName = "XXXXXX";
var allCultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures);
var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.AppSettings["StorageConnection"]);
var blobClient = storageAccount.CreateCloudBlobClient();
var container = blobClient.GetContainerReference("xxxxxx");
var res = container.CreateIfNotExistsAsync().GetAwaiter().GetResult();
var count = BlobEmbeddedFileLocalizationDictionaryProvider.Count;
var listBlobs = container.ListBlobsSegmentedAsync(null, true, BlobListingDetails.None, count, null, null, null).GetAwaiter().GetResult();
foreach (var item in listBlobs.Results)
{
var blockBlob = container.GetBlockBlobReference(((Microsoft.WindowsAzure.Storage.Blob.CloudBlob)item).Name);
string path = _assembly.Location.Replace("xxxxx", "");
path += ((Microsoft.WindowsAzure.Storage.Blob.CloudBlob)item).Name;
blockBlob.DownloadToFileAsync(path, FileMode.OpenOrCreate).GetAwaiter().GetResult();
using (var stream = File.OpenRead(path))
{
var xmlString = Utf8Helper.ReadStringFromStream(stream);
InitializeDictionary(CreateXmlLocalizationDictionary(xmlString), isDefault: ((CloudBlob)item).Name.EndsWith(sourceName + ".xml"));
}
}
}
protected virtual XmlLocalizationDictionary CreateXmlLocalizationDictionary(string xmlString)
{
return XmlLocalizationDictionary.BuildFomXmlString(xmlString);
}
protected void InitializeDictionary<TDictionary>(TDictionary dictionary, bool isDefault = false)
where TDictionary : ILocalizationDictionary
{
if (Dictionaries.ContainsKey(dictionary.CultureInfo.Name))
{
throw new AbpInitializationException(SourceName + " source contains more than one dictionary for the culture: " + dictionary.CultureInfo.Name);
}
Dictionaries[dictionary.CultureInfo.Name] = dictionary;
if (isDefault)
{
if (DefaultDictionary != null)
{
throw new AbpInitializationException("Only one default localization dictionary can be for source: " + SourceName);
}
DefaultDictionary = dictionary;
}
}
}
internal static class Utf8Helper
{
public static string ReadStringFromStream(Stream stream)
{
var bytes = stream.GetAllBytes();
var skipCount = HasBom(bytes) ? 3 : 0;
return Encoding.UTF8.GetString(bytes, skipCount, bytes.Length - skipCount);
}
private static bool HasBom(byte[] bytes)
{
if (bytes.Length < 3)
{
return false;
}
if (!(bytes[0] == 0xEF && bytes[1] == 0xBB && bytes[2] == 0xBF))
{
return false;
}
return true;
}
}
This Provider is executed as expected.
But When I Refresh my client(Angular) Application, I still see the old Translations.
If I restart my API application, new translations are reflected correctly.
Can someone help me to understand, what am I missing here.
Thanks for the help in advance.

Flag / Unflag email sending in CRM 2011

In CRM 2011, I want to attach Contacts to Quote, no problems for that.
When I save the quote, for each Contact I want to send a email for reminder purpose. (With a plugin)
How It's possible to flag this and give the ability to CRM user to unflag this from the quote form with a checkbox.
The final purpose, It's to give the ability to CRM user to send a new email reminder to one or multiple contacts attached in the quote.
Can you help me ?
You will need to have a ribbon button that will call a JavaScript method in one of the web-resources.
In the CommandDefinition of you RibbonDiff XML you will need to send a parameter to the JS method which will contain all the IDs of selected records in the subgrid.
<CommandDefinitions>
<CommandDefinition Id="xyz.Button.SendEmail.command">
<EnableRules>
</EnableRules>
<DisplayRules>
</DisplayRules>
<Actions>
<JavaScriptFunction Library="$webresource:Test.Js" FunctionName="SendEmail">
<CrmParameter Value="SelectedControlAllItemIds" />
</JavaScriptFunction>
</Actions>
</CommandDefinition>
and then the JS method would be something like below wherein you will need to parse all the IDs and then process your logic
function SendEmail(selectedIds) {
if (selectedIds != null && selectedIds != “”) {
var strIds = selectedIds.toString();
var arrIds = strIds.split(“, ”);
for (var indxIds = 0; indxIds < arrIds.length; indxIds++) {
//The logic that you want to process on each record will come here.
}
} else {
alert(“No records selected !! !”);
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Crm;
using Microsoft.Xrm.Sdk;
using System.ServiceModel;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Crm.Sdk.Messages;
using System.Text.RegularExpressions;
using System.Xml.Linq;
namespace SendEmail
{
public class Email : IPlugin
{
public void Execute(IServiceProvider serviceprovider)
{
IPluginExecutionContext context = (IPluginExecutionContext)serviceprovider.GetService(typeof(IPluginExecutionContext));
if (!(context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity))
return;
//entity
Entity ent = (Entity)context.InputParameters["Target"];
if (ent.LogicalName != "entityName")//EntityName
throw new InvalidPluginExecutionException("Not a Service Request record! ");
//service
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceprovider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService _service = serviceFactory.CreateOrganizationService(context.UserId);
string Email="";
if (ent.Contains("emailidfiled"))
Email = (string)ent["emailidfiled"];
#region email template
QueryExpression query = new QueryExpression()
{
EntityName = "template",
Criteria = new FilterExpression(LogicalOperator.And),
ColumnSet = new ColumnSet(true)
};
query.Criteria.AddCondition("title", ConditionOperator.Equal, "templateName");
EntityCollection _coll = _service.RetrieveMultiple(query);
if (_coll.Entities.Count == 0)
throw new InvalidPluginExecutionException("Unable to find the template!");
if (_coll.Entities.Count > 1)
throw new InvalidPluginExecutionException("More than one template found!");
var subjectTemplate = "";
if (_coll[0].Contains("subject"))
{
subjectTemplate = GetDataFromXml(_coll[0]["subject"].ToString(), "match");
}
var bodyTemplate = "";
if (_coll[0].Contains("body"))
{
bodyTemplate = GetDataFromXml(_coll[0]["body"].ToString(), "match");
}
#endregion
#region email prep
Entity email = new Entity("email");
Entity entTo = new Entity("activityparty");
entTo["addressused"] =Email;
Entity entFrom = new Entity("activityparty");
entFrom["partyid"] = "admin#admin.com";
email["to"] = new Entity[] { entTo };
email["from"] = new Entity[] { entFrom };
email["regardingobjectid"] = new EntityReference(ent.LogicalName, ent.Id);
email["subject"] = subjectTemplate;
email["description"] = bodyTemplate;
#endregion
#region email creation & sending
try
{
var emailid = _service.Create(email);
SendEmailRequest req = new SendEmailRequest();
req.EmailId = emailid;
req.IssueSend = true;
GetTrackingTokenEmailRequest wod_GetTrackingTokenEmailRequest = new GetTrackingTokenEmailRequest();
GetTrackingTokenEmailResponse wod_GetTrackingTokenEmailResponse = (GetTrackingTokenEmailResponse)
_service.Execute(wod_GetTrackingTokenEmailRequest);
req.TrackingToken = wod_GetTrackingTokenEmailResponse.TrackingToken;
_service.Execute(req);
}
catch (Exception ex)
{
throw new InvalidPluginExecutionException("Email can't be saved / sent." + Environment.NewLine + "Details: " + ex.Message);
}
#endregion
}
private static string GetDataFromXml(string value, string attributeName)
{
if (string.IsNullOrEmpty(value))
{
return string.Empty;
}
XDocument document = XDocument.Parse(value);
// get the Element with the attribute name specified
XElement element = document.Descendants().Where(ele => ele.Attributes().Any(attr => attr.Name == attributeName)).FirstOrDefault();
return element == null ? string.Empty : element.Value;
}
}
}

Attaching a event receiver to a content type

I created some site columns / a content type and a list definition as part of a feature. I want to attach an eventreceiver to the content type. I added code to attach the event receiver to the content type. Using spmanager i can see that the event receiver is attached to the content type however when i create lists from the content type the event reciever is missing. Any ideas. My code is below
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
string asmName = System.Reflection.Assembly.GetExecutingAssembly().FullName;
string itemReceiverName = "xxxxxx.Intranet.SP.xxxxx.PermissionsUpdaterEventReceiver";
////surely a better way to get all lists than this
////re - do
using (SPSite thisSite = (SPSite)properties.Feature.Parent) {
using (SPWeb web = thisSite.RootWeb) {
SPContentType RambollNewsContentType = web.ContentTypes["RambollNewsContentType"];
RambollNewsContentType.EventReceivers.Add(SPEventReceiverType.ItemAdded, asmName, itemReceiverName);
RambollNewsContentType.Update(true);
}
}
}
I am using this successfully. I left in my logging and the logging method.
/// <summary>
/// This method is executed on feature activation.
/// It attaches the event receiver to the content type.
/// </summary>
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
LogMessage("FeatureActivated - Start");
SPSite site = (SPSite)properties.Feature.Parent;
LogMessage("FeatureActivated - 1");
SPWeb web = site.RootWeb;
LogMessage("FeatureActivated - 2");
//ListContentTypes(web);
SPContentType ctype = web.ContentTypes["Wells Project Task List"];
LogMessage("FeatureActivated - 3");
LogMessage("ctype name: " + ctype.Name.ToString());
if (ctype != null)
{
LogMessage("FeatureActivated - I have a content type. Web url: " + web.Url);
SPEventReceiverDefinition er = ctype.EventReceivers.Add();
er.Class = "Wells.SharePoint.ProjectManagementEventReceiver";
er.Assembly = "ProjectManagementEventReceiver, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a1cb21c41d80b7ae";
er.Type = SPEventReceiverType.ItemAdded;
er.Name = "ItemAdded";
er.SequenceNumber = 10001;
er.Update();
ctype.Update(false);
LogMessage("FeatureActivated - After ctype.update");
web.Dispose();
}
else
LogMessage("CT not found: " + web.Url);
LogMessage("FeatureActivated - End");
}
static void ListContentTypes(SPWeb web)
{
foreach (SPContentType ct in web.ContentTypes)
{
LogMessage("CT: " + ct.Name.ToString());
}
}
/// <summary>
/// This method is executed on feature deactivation.
/// It removes the event receiver from the content type
/// </summary>
/// <param name="properties"></param>
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
LogMessage("Feature DeActivated - Start");
SPSite site = (SPSite)properties.Feature.Parent;
SPWeb web = site.OpenWeb();
SPContentType contentType = web.ContentTypes["NAME OF CONTENT TYPE"];
if (contentType != null)
{
LogMessage("im have a content type. Web url: " + web.Url);
int i;
//Use the above integer to loop through the event recievers on the first list and delete the above assembly
for (i = 0; i < contentType.EventReceivers.Count; i++)
{
LogMessage("ER Count: " + contentType.EventReceivers.Count);
if (contentType.EventReceivers[i].Assembly.Contains("ProjectManagementEventReceiver"))
{
contentType.EventReceivers[i].Delete();
LogMessage("Deleting event receiver from CT");
}
}
contentType.Update();
}
else
LogMessage("CT not found: " + web.Url);
LogMessage("Feature DeActivated - End");
}
static void LogMessage(string msg)
{
StreamWriter wrtr = null;
try
{
wrtr = new StreamWriter("C:\\Logs\\FeatureActivatedDeactivated.txt", true);
wrtr.WriteLine(msg + "--[" + System.DateTime.Now.ToString() + "]" + Environment.NewLine);
wrtr.WriteLine(Environment.NewLine + "==================================");
}
catch (Exception e)
{
throw e;
}
finally
{
if (wrtr != null)
{
wrtr.Close();
wrtr.Dispose();
}
}
}
I am not sure is this related to your question or not but
but could you try to add the event receiver to the content type before you add the content type to the list.
I think the event receiver has to be added before because when adding a content type to a list the content type is not added directly to the list, rather a copy of it is added to the list. So when you add your content type to the list, there is no event receiver yet.
Correct me if i understand your question wrong?
Thanks

Windows 8 Emulator Snap State

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.

DataBinding Snapped Mode Windows 8

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.