I am using picker in my xaml like
<Picker x:Name="pickerService" HorizontalOptions="Center" VerticalOptions="CenterAndExpand" ItemDisplayBinding="{Binding ServiceName}"/>
My Service class is like
public class Service
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string ServiceName { get; set; }
}
and adding list to picker itemssource like
List<Service> serviceNames = new List<Service>();
serviceNames = App.DAUtil.GetServices ();
pickerService.ItemsSource = serviceNames ;
here I am getting serviceNames list from my local db.When I select a service from picker sometimes it is showing class name at zero position instead of "ServiceName", like "App.MainPage". Please help me to solve this.
Related
i want to be able to take a picture with the emulator, have it create and save an item on the database and display properly on my main Item Page, how do I go about doing this?
i tried my best to only show what is important and related to this and therefore have cut a bunch of stuff out(for example my View for adding items isnt present because i THINK the only part relating to this is the button with a command binding to it leading to the viewmodel)
the reason im asking here is because there are no errors showing, the application doesnt start at all like this and im really confused, i appreciate any and all help and thank you in advance.
if you need any additional info about anything related to this please do ask and i will share it as soon as i see your messeage.
my Item.cs
{
[PrimaryKey, AutoIncrement]
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string LongDescription { get; set; }
public MediaFile Image { get; set; }
public string Quantity { get; set; }
public string TypeOfQuantity { get; set; }
}
my main page Listview (without the unimportant parts in XAML)
<ListView>
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Item">
<ViewCell Height="220" xct1:ShadowEffect.Radius="5">
<Grid Padding="7">
<Frame CornerRadius="15">
<StackLayout Orientation="Horizontal">
...// bunch of labels and what not//
</StackLayout>
</StackLayout>
</Frame>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
the Item Creating ViewModel (unrelated things cut out)
public string Name { get; set; }
public string ShDesc { get; set; }
public string LgDesc { get; set; }
public string Qty { get; set; }
public MediaFile Image { get; set; }
public string TypeOfQty { get; set; }
public AsyncCommand AddCommand { get; }
public AsyncCommand PicCommand { get; }
public ItemAddViewModel()
{
AddCommand = new AsyncCommand(Add);
PicCommand = new AsyncCommand(Pic);
}
async Task Add()
{
var name = Name;
var description = ShDesc;
var longdescription = LgDesc;
var qty = Qty;
var typeofqty = TypeOfQty;
var image = Image;
await ItemService.AddItem(name, description, longdescription, qty, typeofqty, image);
Name = ShDesc = LgDesc = Qty = TypeOfQty = null;
}
async Task Pic()
{
var photo = await CrossMedia.Current.TakePhotoAsync(
new StoreCameraMediaOptions
{
SaveToAlbum = true
});
Image = photo;
}
}
}
my Services and DB
public static class ItemService
{
static SQLiteAsyncConnection db;
static async Task Init()
{
//creats Database if it doesnt exist
if (db != null)
return;
var databasePath = Path.Combine(FileSystem.AppDataDirectory, "Mydata.db");
db = new SQLiteAsyncConnection(databasePath);
await db.CreateTableAsync<Item>();
}
//adds item to database
public static async Task AddItem(string Name, string Description,string LongDescription, string Quantity, string TypeOfQuantity, MediaFile image)
{
await Init();
var item = new Item
{
Name = Name,
LongDescription = LongDescription,
Description = Description,
Quantity = Quantity,
TypeOfQuantity = TypeOfQuantity,
Image = image
};
await db.InsertAsync(item);
}
need to ask you a hand with this one.
I'm currently developing a Xamarin Forms solution using MVVM and i'm in a new situation right now.
I've got a listView with items made by this class
public class City
{
public int Key { get; set; }
public string Value { get; set; }
public List<string> Words{ get; } = new List<string> { "One", "Two", "Three" };
}
What I want to achieve is to display a label text created using the Words list elements indicized by Key. Something like
Words[Key]
Example
<ListView
ItemsSource="{Binding Cities}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout
HorizontalOptions="FillAndExpand"
VerticalOptions="StartAndExpand">
<Label Text="{Binding Words[Key]}"
FontSize="18"
TextColor="Black"
VerticalOptions="StartAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The label text binding doesn't work, but tecnically is what i need to achieve. For example, if i use Words[0] it will work and returns 'One'
My ViewModel is pretty simple.
public class TestViewModel : INotifyPropertyChanged
{
public ObservableCollection<City> Cities { get; set; }
public TestViewModel()
{
Cities = GetCities();
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public ObservableCollection<City> GetCities()
{
return new ObservableCollection<City>
{
new City {Key = 1, Value = "Mumbai"},
new City {Key = 2, Value = "New York"},
new City {Key = 3, Value = "Milan"},
new City {Key = 4, Value = "Rome"}
};
}
}
Do i need to create a property for indexing? In my opinion the problem is that i'm inside a list and already have an index to use.
Thanks for help guys
You can modify your model :
public class City
{
public int Key { get; set; }
public string Value { get; set; }
public List<string> Words { get; } = new List<string> { "One", "Two", "Three" };
public string myValue
{
get
{
return Words[Key];
}
set {}
}
}
And in your .xmal, just set Text="{Binding myValue}" and it will display a list element value of Words.
Need some direction/help here guys. Similar to a basic contacts app - I'm building a customer entry screen and need a drop down for contact types (phone, email, etc). I figured out how to populate the picker(s) by explicitly defining the path and source but I can't seem to get SelectedItem to do anything. My expectation is set the default value of the picker with whats in the record and also be able to change that value.
<ListView x:Name="ContactListView" ItemsSource="{Binding Customer.ContactList}" >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout>
<Picker
ItemsSource="{Binding Path=BindingContext.ContactTypes, Source={x:Reference ContactListView} }"
ItemDisplayBinding="{Binding TypeName}"
SelectedItem="{Binding TypeName, Mode=TwoWay}"
/>
<Entry Text="{Binding Value}" />
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
The ViewModel attached to this page is a Customer object which has a nested contact list in it (defined at the list view). Below is a basic version of the Customer Class that I'm using on the page with its relationship to ContactTypes.
public class Customer
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string AddressLine { get; set; }
public string City { get; set; }
public string State { get; set; }
public string Country { get; set; }
public List<Contact> ContactList { get; set; }
}
public class ContactType
{
public string TypeName { get; set; }
public int SortOrderId { get; set; }
}
public class Contact : ContactType
{
public int Id { get; set; }
public string Value { get; set; }
}
When the Page ViewModel loads, I store a list of possible ContactTypes (one time) that the user can choose from and it's shared in each picker as the item source. The list of possible ContactTypes from the database are stored in a local variable - here's the static representation of it:
public IList<ContactType> ContactTypes { get; } = new List<ContactType>
{
new ContactType(){ TypeName = "Home Phone", SortOrderId = 1 },
new ContactType(){ TypeName = "Cell Phone", SortOrderId = 2 },
new ContactType(){ TypeName = "Work Phone", SortOrderId = 3 },
new ContactType(){ TypeName = "Email", SortOrderId = 4 },
new ContactType(){ TypeName = "Fax", SortOrderId = 5 }
};
I need the picker to show the options from ContactTypes, and when an Item is Selected, it updates the TypeName property of the current record iteration in ContactList.
I am trying to bind the values for a picker from a model in view model, there I am getting path of the model instead of the values.
<Picker x:Name="LocationPicker"
Title="Location" HeightRequest="40"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
SelectedItem="{Binding Location}"
ItemsSource="{Binding MaintainRoomTypes}"/>
Here is my view model code:
if (jobDetailsForFitter != null)
{
WindowDetails = new WindowDetailsModel
{
Windows = jobDetailsForFitter.Windows,
Locations = jobDetailsForFitter.Locations,
RoomTypes = jobDetailsForFitter.RoomTypes,
AddFiles = jobDetailsForFitter.AddFiles
};
Locations = jobDetailsForFitter.Locations;
MaintainRoomTypes = jobDetailsForFitter.RoomTypes;
await FitterService.Instance.LoadJobDetailsToLocalStore(jobDetailsForFitter, SelectedJob?.Id ?? 0);
}
how to bind itemsource to get list.
public List<Room> Locations { get; set; }
public List<RoomTypeModel> RoomTypes { get; set; }
You have to define ItemDisplayBinding property to Picker.
For eg:
public class Room
{
public string RoomNumber { private set; get; }
public string RoomName { private set; get; }
}
And you want to display RoomName in Picker
<Picker ItemsSource="{Binding Room}" ItemDisplayBinding="{Binding RoomName}"/>
Hope this will solve your problem.
I have these classes:
public class MovieExt
{
public string Title { get; set; }
public string Year { get; set; }
public List<string> Genres { get; set; }
public List<Actor> Actors { get; set; }
....
}
public class Actor
{
public string Name { get; set; }
public string Birth { get; set; }
public string Biography { get; set; }
public string Url { get; set; }
}
and this is my method in my page:
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
object obj;
if (PhoneApplicationService.Current.State.TryGetValue("movie", out obj))
{
MovieExt movie = (MovieExt)obj;
this.DataContext = movie;
this.imgPoster.Source = new BitmapImage(new Uri(movie.PosterUrl, UriKind.Absolute));
}
base.OnNavigatedTo(e);
}
and in page I am binding properties like this:
<ListBox Grid.Row="4" Grid.Column="1"
Margin="5,5,5,5"
ItemsSource="{Binding Path=Actors }"
x:Name="listStars"/>
For everything it´s working (genres and others). Everything else is string. But for actors I want to bind in list name and after clicking on the actor I want to go to url. How can I bind name property from actor? Thanks
First of all, you need to create OnSelectedItemChanged event on your ListBox to handle clicks on your Actors.
Then you need to get your clicked item. You can do this in several ways. The simplest way is listBox.SelectedItem property.
And then your can get your Url with (listBox.SelectedItem as Actor).Url
Also, when you go back from details page, SelectedItem will be not null and click on the same item not fired event in second time. So, set SelectedItem to null when click is handled
UPD: to properly bind Actor class to ListBox you need to create ItemTemplate:
<ListBox ...>
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text={Binding Name} />
<TextBlock Text={Binding Birth} />
<TextBlock Text={Binding Biography} />
<TextBlock Text={Binding Url} />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can override the ToString() method in the Actor class to display something friendly, like the name.
public override string ToString()
{
return Name;
}
This is useful when binding objects to comboboxes and dropdowns.