Adding Xamarin app a searchbar - sqlite

I made a simple Xamarin Cross platform SQLite app which can inserts, updates, deletes data from a listview. I want to add a searchbar. Following this tutorial i added this on my HomePage.xaml
Now if my listview's source was a list just like in the tutorial i had to write this in HomePage.xaml.cs
private void mySearchBar_ButtonPressed(object sender, EventArgs e)
{
string searchText = mySearchBar.Text;
myListView.ItemsSource=ListViewsListSource.Where(name=>name.Contains(searchText ));
}
But i defined my listview's source like this.
using (var dataaccess= new DataAccess())
{
listaListView.ItemsSource = dataaccess.GetEmployers();
}
And GetEmployers is defined in DataAccess
public List<Employer> GetEmployers()
{
return connection.Table<Employer>().OrderBy(c => c.Lastname).ToList();
}
Now what should i write in mySearchBar_ButtonPressed ?

There are a lot of different ways to approach this. Following your own example, you could add a Search method to your DataAccess class
public List<Employer> SearchEmployers(string key)
{
return connection.Table<Employer>().Where(e => e.Lastname.Contains(key) || e.FirstName.Contains(key)).OrderBy(c => c.Lastname).ToList();
}
private void mySearchBar_ButtonPressed(object sender, EventArgs e)
{
string searchText = mySearchBar.Text;
listaListView.ItemsSource = dataaccess.SearchEmployers(searchText);
}

Related

How can I create a custom renderer for DatePicker for UWP?

I'm trying to create a custom DatePicker renderer for UWP but I'm getting a compile error.
Trying to get a CalenderDatePicker instead of the normal DataPicker. I am getting the same error whether I try one or the other.
My code is:
CustomControl.cs
namespace myNameSpace.CustomControl
{
public class CustomDatePicker : DatePicker
{
}
}
And my CustomDatePickerRenderer.cs in the UWP folder
[assembly: ExportRenderer(typeof(CustomDatePicker), typeof(CustomDatePickerRenderer))]
namespace myNameSpace.UWP
{
public class CustomDatePickerRenderer : ViewRenderer<DatePicker, Windows.UI.Xaml.Controls.CalendarDatePicker>, ITabStopOnDescendants, IDontGetFocus
{
protected override void OnElementChanged(ElementChangedEventArgs<DatePicker> e)
{
base.OnElementChanged(e);
if (Control == null)
{
Windows.UI.Xaml.Controls.CalendarDatePicker datePicker = new Windows.UI.Xaml.Controls.CalendarDatePicker();
SetNativeControl(datePicker);
}
}
}
}
The error I get is:
The type 'Windows.UI.Xaml.Controls.DatePicker' cannot be used as type parameter 'TElement' in the generic type or method 'ViewRenderer<TElement, TNativeElement>'. There is no implicit reference conversion from 'Windows.UI.Xaml.Controls.DatePicker' to 'Xamarin.Forms.View'.
From the documentation I can find this should be ok - is it not possible to create a custom renderer for the DatePicker? Please help.
This might not be a big thing by experiences developers, but I'm thrilled that I got it working - substituting the Xamarin.Forms DataPicker with the UWP CalendarDatePicke - so I'll just post my working solution, if someone else could use it.
Thanks to pinedax for solving my initial problem - which I actually changed to my CustomDatePicker in the end, because this is what is in the documentation from MS.
The last thing I needed was to ensure that Date changes where registered between to two different controls, since they use different events for this.
My code is:
CustomDatePicker.cs
namespace myNameSpace.CustomControl
{
public class CustomDatePicker : DatePicker
{
}
}
CustomDatePickerRenderer.cs in the UWP folder
[assembly: ExportRenderer(typeof(CustomDatePicker), typeof(CustomDatePickerRenderer))]
namespace myNameSpace.UWP
{
public class CustomDatePickerRenderer : ViewRenderer<CustomDatePicker, Windows.UI.Xaml.Controls.CalendarDatePicker>
{
protected override void OnElementChanged(ElementChangedEventArgs<CustomDatePicker> e)
{
base.OnElementChanged(e);
if (e.OldElement != null)
{
// Unsubscribe from event handlers and cleanup any resources
Control.DateChanged -= OnDateChanged;
Element.DateSelected -= OnDateSelected;
}
if (e.NewElement != null)
{
if (Control == null)
{
// Instantiate the native control and assign it to the Control property with
// the SetNativeControl method
if (Control == null)
{
Windows.UI.Xaml.Controls.CalendarDatePicker datePicker = new Windows.UI.Xaml.Controls.CalendarDatePicker();
datePicker.FirstDayOfWeek = Windows.Globalization.DayOfWeek.Monday;
SetNativeControl(datePicker);
}
}
Control.DateChanged += OnDateChanged;
Element.DateSelected += OnDateSelected;
}
}
private void OnDateChanged(CalendarDatePicker sender, CalendarDatePickerDateChangedEventArgs e)
{
DateTimeOffset dto = (DateTimeOffset)e.NewDate;
Element.Date = dto.DateTime;
}
private void OnDateSelected(Object sender, DateChangedEventArgs e)
{
DateTime dt = e.NewDate;
Control.Date = new DateTimeOffset(dt);
}
}
}
And I can now reference my CustomDatePicker (UWP CalendarDatePicker) from my Xamarin.Forms XAML file
<local:CustomDatePicker x:Name="FilterDatePicker" DateSelected="OnDateFilterDateChanged" VerticalOptions="Center"></local:CustomDatePicker>
That's because it's not using the correct DatePicker.
That method expects the Xamarin.Forms.DatePicker but instead it's referencing the Windows.UI.Xaml.Controls.DatePicker.
To fix it either use the long namespace
[assembly: ExportRenderer(typeof(CustomDatePicker), typeof(CustomDatePickerRenderer))]
namespace myNameSpace.UWP
{
public class CustomDatePickerRenderer : ViewRenderer<Xamarin.Forms.DatePicker, Windows.UI.Xaml.Controls.CalendarDatePicker>, ITabStopOnDescendants, IDontGetFocus
{
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.DatePicker> e)
{
base.OnElementChanged(e);
if (Control == null)
{
Windows.UI.Xaml.Controls.CalendarDatePicker datePicker = new Windows.UI.Xaml.Controls.CalendarDatePicker();
SetNativeControl(datePicker);
}
}
}
}
Or use the using notation at the top of your class to indicate which one to use. Something like
using DatePicker = Xamarin.Forms.DatePicker;
Hope this helps.-

user.Roles.FirstOrDefault() returns DynamicProxy

OK...
I was finally making some headway with creating a User Management page using Identity 2 in Web Forms.
It was mostly moving along just fine. When suddenly I run into this issue, and it makes no sense to me.
I have an AS form with a dropdown list of Roles. That list is populated using
roleMgr.Roles.ToList();
Works Great
I use the user being edited Role to set the current selected value.
ddlUserType.SelectedValue = user.Roles.FirstOrDefault().ToString();
This WAS working like dynamite
Last week...
Now all of a sudden user.Roles.FirstOrDefault().ToString(); is returning
"System.Data.Entity.DynamicProxies.IdentityUserRole_FDDE5D267CF62D86904A3BC925D70DC410F12D5BE8313308EC89AC8537DC6375"
What he heck, man?
So I tried user.Roles.Take(1).ToString();
That returns
"System.Linq.Enumerable+d__24`1[Microsoft.AspNet.Identity.EntityFramework.IdentityUserRole]"
I have to presume I Broke, Something...
But What?
Nothing in this code page changed at all between when it worked and then didn't.
The only thing I did related to Identity at all was Migrate a couple of fields into AspNetUsers (another whole ballgame, migrations...) which also worked like dynamite BTW.
I even went to the extreme of wiping out my Migrations and AspNet user tables entirely, and re-initializing it all.
Any suggestions ?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Sperry_Parts.Models;
using Sperry_Parts.Logic;
using Microsoft.AspNet.Identity.Owin;
using Owin;
namespace Parts.Admin
{
public partial class CreateEditUser : System.Web.UI.Page
{
private bool NewUser
{
get { return ViewState["NewUser"] != null ? (bool)ViewState["NewUser"] : false; }
set { ViewState["NewUser"] = value; }
}
private string EditUser
{
get { return (string)ViewState["EditUser"]; }
set { ViewState["EditUser"] = value; }
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
EditUser = Session["Edit_User"].ToString();
// Access the application context and create result variables.
Models.ApplicationDbContext context = new ApplicationDbContext();
RoleActions roleAction = new RoleActions();
// Create a RoleStore object by using the ApplicationDbContext object.
var roleStore = new RoleStore<IdentityRole>(context);
// Create a RoleManager object that is only allowed to contain IdentityRole objects.
var roleMgr = new RoleManager<IdentityRole>(roleStore);
// Load the DDL of Roles
var roles = roleMgr.Roles.ToList();
ddlUserType.DataTextField = "Name";
ddlUserType.DataValueField = "Id";
ddlUserType.DataSource = roles;
ddlUserType.DataBind();
if (EditUser == "")
{
txtUserName.Enabled = true;
txtUserName.Focus();
NewUser = true;
} // End New User
else
{
// User part
var userMgr = Context.GetOwinContext().GetUserManager<ApplicationUserManager>();
var signinManager = Context.GetOwinContext().GetUserManager<ApplicationSignInManager>();
txtUserName.Enabled = false;
txtFullName.Focus();
var user = userMgr.FindByName(EditUser);
if (user != null)
{
txtUserName.Text = user.UserName;
txtUserEmail.Text = user.Email;
txtFullName.Text = user.FullName;
var hisroles = user.Roles.ToList(); // properly returns 1 item
// this is where it went off the rails - these 4 lines are debugging code
string xrole = user.Roles.FirstOrDefault().ToString();
string role2 = user.Roles.Take(1).ToString();
string trythis = xrole.ToString();
string trythis2 = role2.ToString();
// I swear, this worked last week...
ddlUserType.SelectedValue = user.Roles.FirstOrDefault().ToString();
}
} // End Editing User
} // End if (!IsPostBack)
} // End Page Load
protected void CreateUser()
{
// removed as non-relevant to question
} // End CreateUser
protected void UpdateUser()
{
// removed as non-relevant to question
} // End UpdateUser
protected void btnSave_Click(object sender, EventArgs e)
{
// removed as non-relevant to question
} // End btnSave
protected void btnCancel_Click(object sender, EventArgs e)
{
Response.Redirect("~/ManageUsers");
} // End btnCancel
} // End Class CreateEditUser
}
I ran into the same problem trying to set the value of a "Roles" DropDownList inside a GridView Control. I solved it by using:
user.Roles.First().RoleId
It just happens that my RoleId is also my role name.

Binding 2 dropdownlist with LINQ

Im stuck in my project here and i really need some help!
I have 2 dropdownlists "DropDownPostal" and "DropDownCity". When the user/employee logges into the system, he gets the list of Postals in the first dropdown list. Lets say he choose a postal and tabs over to the second dropdown "city". I want city to be updated with the postal the user choose earlier. I have everything working with the login and retrieving data from the database to the DropDownPostal. But I cannot get the other DropDownCity updated with any data!
Here is my code for the event i made for the postaldropdown, Im trying to make a "onLeave" event.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace Test
{
public partial class WebForm1 : System.Web.UI.Page
{
// Entity
DanxWebsiteEntities dwe = new DanxWebsiteEntities();
protected void Page_Load(object sender, EventArgs e)
{
//Dropdown postback
//DropDownListPostal.AutoPostBack = false;
//Sessions
if (Session["UserID"] == null && Session["Name"] == null)
{
Response.Redirect("Error.aspx");
}
else
{
msg1.Text = "User id: "+Session["UserID"].ToString();
msg2.Text = "User Name: " + Session["Name"].ToString();
}
//Update dropdownpostal
if (!IsPostBack)
{
//Guid is structure type
Guid id =(Guid) Session["UserID"];
DropDownListPostal.DataSource = (from custumAdr in dwe.VW_CustumAddress
where custumAdr.UserID ==(Guid)id
select custumAdr).ToList();
DropDownListPostal.DataTextField = "Postal";
DropDownListPostal.DataValueField = "UserID";
DropDownListPostal.DataBind();
}
}
protected void DropDownListPostal_SelectedIndexChanged1(object sender, EventArgs e)
{
foreach (var data in dwe.VW_CustumAddress)
if (data.Postal == DropDownListPostal.SelectedItem.ToString())
{
DropDownListBy.Text = data.City;
}
else
{
}
}
}
}
Im not even sure if this code is close to correct.
Detailed help with code will be much appreciated.
Cheers :-)
If I understood you right, you only need to change the value displayed in dropDownListCity according to the value selected in dropDownListPostal. To do so, you need to bind both dropdown lists in Page_Load and then handle the selected index when SelectedIndexChanged is triggered.
private IEnumerable<KeyValuePair<string, string>> GetData()
{
using(var dataContext = new DbEntities())
{
return dataContext.VW_CustumAddress
.ToList()
.Select(item => new KeyValuePair<string, string>(item.Postal, item.City))
.ToArray();
}
}
protected void Page_Load(object sender, EventArgs e)
{
if(!IsPostback)
{
IEnumerable<KeyValuePair<string,string>> data = GetData();
//Bind Postal dropdown list
dropDownListPostal.DataSource = data.Select(kvp => kvp.Key).ToList();
// ^ Select only 'Postal' column in dropdown list.
dropDownListPostal.DataBind();
// Bind City dropdown list
// We need to bind to a key-value pair to know the correspondence between items
dropDownListCity.DataValueField = "Key";
dropDownListCity.DataTextField = "Value";
dropDownListCity.DataSource = data;
dropDownListCity.DataBind();
}
}
Now, after you bound your controls to data you only need to handle SelectedIndexChanged event of dropDownListPostal (don't forget to set AutoPostback="true" in the markup of dropDownListPostal).
EDIT: Before selecting an item, clear the selection of your dropdown list to make sure only one item is selected.
protected void OnDropDownListPostalSelectedIndexChanged(object sender, EventArgs e)
{
dropDownListCity.ClearSelection();
var postal = dropDownListPostal.SelectedValue;
var listItem = dropDownListCity.Items.FindByValue(postal);
listItem.Selected = true;
}
That should do it. Hope it helps.
Make sure DropDownListPostal has AutoPostBack = True
You have no DropDownListPostal.DataBind() in your code, so the data you're assigning to it is not being bound. Make sure this is called after the data is assigned with the .DataSource.
As you have mentioned here
//Dropdown postback
//DropDownListPostal.AutoPostBack = false;
Please make it True.
<asp:DropDownList ID="DropDownListPostal" runat="server" AutoPostBack="true" OnSelectedIndexChanged="DropDownListPostal_SelectedIndexChanged"></asp:DropDownList>
Instead of using DropDownListBy.Text = data.City;
You can select Dropdown list by Value also,.
DropDownListBy.SelectedValue = data.id
Hope this will help you
You can try with this code
//You must bind your datas before set Text Value
DropDownListBy.DataSource =...;
DropDownListBy.DataBind();
DropDownListBy.Text = data.City;
Link : http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listcontrol.text.aspx
Or you can also
DropDownListBy.Items.Add(data.City);

Why am I losing object references on the postback?

I am developing an asp.net (3.5) application and I am puzzled with the behavior of the postbacks.
Consider the following scenario: I have a web user control that is basically a form. However each form field is a web user control in itself.
In the click event of the save button I iterate through all controls in my form and I retrieve the field value and the field name that refers to the database field that I am saving the value to.
The click event triggers a postback and it is during the postback that I visit the controls and here is the funny thing: the property value for the database field has become null! Could anyone shed a light here?
Here is some basic code:
[Serializable]
public partial class UserProfileForm : CustomIntranetWebappUserControl
{
protected override void OnInit(EventArgs e)
{
//AutoEventWireup is set to false
Load += Page_Load;
CancelLinkButton.Click += CancelButtonClickEvent;
SaveLinkButton.Click += SaveButtonClickEvent;
base.OnInit(e);
}
private void SaveButtonClickEvent(object sender, EventArgs e)
{
VisitFormFields();
}
private void VisitFormFields()
{
var userProfileVisitor = new UserProfileVisitor();
foreach (var control in Controls)
{
if (control is FormFieldUserControl)
{
var formField = (FormFieldUserControl) control;
formField.Visit(userProfileVisitor);
}
}
userProfileVisitor.Save();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
BindText();
}
}
private void BindText()
{
LastNameFormLine.LabelText = string.Format("{0}:", HomePage.Localize("Last Name"));
LastNameFormLine.InputValue = UserProfile.LastName;
LastNameFormLine.IsMandatoryField = true;
LastNameFormLine.IsMultilineField = false;
LastNameFormLine.ProfileField = "UserProfile.LastName";
//... the rest of this method is exactly like the 4 lines above.
}
}
[Serializable]
public abstract class FormFieldUserControl : CustomIntranetWebappUserControl
{
public string ProfileField { get; set; }
public abstract void Visit(UserProfileVisitor userProfileVisitor);
}
[Serializable]
public partial class FormLineTextBox : FormFieldUserControl
{
//... irrelevant code removed...
public override void Visit(UserProfileVisitor userProfileVisitor)
{
if (userProfileVisitor == null)
{
Log.Error("UserProfileVisitor not defined for the field: " + ProfileField);
return;
}
userProfileVisitor.Visit(this);
}
}
[Serializable]
public class UserProfileVisitor
{
public void Visit(FormLineTextBox formLine)
{
// The value of formLine.ProfileField is null!!!
Log.Debug(string.Format("Saving form field type {1} with profile field [{0}] and value {2}", formLine.ProfileField, formLine.GetType().Name, formLine.InputValue));
}
// ... removing irrelevant code...
public void Save()
{
Log.Debug("Triggering the save operation...");
}
}
Remember ASP.NET is stateless. Any properties created are destroyed after the page has been render to the browser. So you have to recreate objects on each post back or store them in View, Session, or Application State.
When you do a property you have to tell it to save the view state it does not do it automatically. Here is a sample of a view state property.
public string SomePropertyAsString
{
get
{
if (this.ViewState["SomePropertyAsString"] == null)
return string.Empty;
return (string)this.ViewState["SomePropertyAsString"];
}
set { this.ViewState["SomePropertyAsString"] = value; }
}
public MyCustomType ObjectProperty
{
get
{
if (this.ViewState["ObjectProperty"] == null)
return null;
return (MyCustomType)this.ViewState["ObjectProperty"];
}
set { this.ViewState["ObjectProperty"] = value; }
}
First guess would be that BindText() shouldn't be in Page_Load, but in Page_Init, so the control state will be saved.
#David Basarab, this is not true afaik, and was only the case in .Net 1.1, in .Net2 and up this is all handled by the framework if you do all the magic stuff in the Init.
Your problem is that 'ProfileField' isn't available on the Postback, right?
The solution is to store the value for that in ViewState (instead of an auto-implemented property). Without that, it won't be available on the postback.

error creating tile for microsoft-band

I have been getting errors when trying to create a tile on my band. I can't seem to get through it. Here is the error:
namespace Band_Test_3
{
#if !DISABLE_XAML_GENERATED_MAIN
public static class Program
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
static void Main(string[] args)
{
global::Windows.UI.Xaml.Application.Start((p) => new App());
}
}
#endif
partial class App : global::Windows.UI.Xaml.Application
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
private bool _contentLoaded;
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Windows.UI.Xaml.Build.Tasks"," 4.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent()
{
if (_contentLoaded)
return;
_contentLoaded = true;
#if DEBUG && !DISABLE_XAML_GENERATED_BINDING_DEBUG_OUTPUT
DebugSettings.BindingFailed += (sender, args) =>
{
global::System.Diagnostics.Debug.WriteLine(args.Message);
};
#endif
#if DEBUG && !DISABLE_XAML_GENERATED_BREAK_ON_UNHANDLED_EXCEPTION
UnhandledException += (sender, e) =>
{
if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
};
#endif
}
}
}
Using this code. The error is happening on the andClient.TileManager.AddTileAsync(tile) line:
private async void btnCreateTile_Click(object sender, RoutedEventArgs e)
{
txbMessage.Text = "";
// create a new Guid for the tile
// create a new tile with a new Guid
BandTile tile = new BandTile(tileGuid)
{
// enable badging (the count of unread messages)
IsBadgingEnabled = true,
// set the name
Name = "Band Test",
// set the icons
SmallIcon = await LoadIcon("ms-appx:///Assets/Certificate-WF Small.png"),
TileIcon = await LoadIcon("ms-appx:///Assets/Certificate-WF.png")
};
await bandClient.TileManager.AddTileAsync(tile);
}
The most common errors I have seen for failing to add a tile are:
Duplicate GUID for the tile as one already on the band. If you have installed the sample tiles with the sample apps then make sure you are using a GUID that is different from the sample apps. The best thing here is to generate your own GUID for your tile.
Maximum number of tiles are installed on the band. To check this, the exception should contain the error message, but you can query the number of tiles installed or you can look at the number installed via the Microsoft Health App in the Manage Tiles view (the number of tiles free is listed towards the top).
If those do now help, then please past in the exception you are getting.

Resources