New Bindable Picker can't set default item from viewmodel - xamarin

Trying to get the new bindable picker to work in Xamarin Forms version 2.3.4.270 with Visual Studio 2017.
I can get the view to load in a list from the view model so when you click the picker, it does show the list of items. I want to set a default item in the picker on screen load though and nothing I have tried is working.
View:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:BindablePickerTest"
x:Class="BindablePickerTest.MainPage">
<StackLayout>
<Label Text="Welcome to Xamarin Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />
<Picker Title="Test Picker" ItemsSource="{Binding Names}" SelectedItem="{Binding Name, Mode=TwoWay}" />
</StackLayout>
</ContentPage>
View Code Behind: (the view model is in the code behind for simplicity)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace BindablePickerTest
{
public partial class MainPage : ContentPage
{
MainPageViewModel vm;
public MainPage()
{
InitializeComponent();
this.BindingContext = vm = new MainPageViewModel();
}
}
public class MainPageViewModel : INotifyPropertyChanged
{
List<string> names = new List<string>
{
"Doug",
"Fred",
"Steve",
"Tom",
"Victor"
};
public List<string> Names => names;
public string Name = "Steve";
public event PropertyChangedEventHandler PropertyChanged;
}
}
When this runs, the picker is still empty - "Steve" is not selected. When clicking the picker, the list shows correctly and I can choose any name, but it will not set a default selection.
Any help is appreciated!

Name is a field right now. For Binding to work - it needs to be converted to property.
public string Name => "Steve";

Related

Xamarin, how to create csutom control which accepts content using xaml?

I'm trying to make a custom control that provides some standard layout for dialogs, where there's button on the top right (within a grid) which has a property for the command and can be used like a StackLayout with content passed into it.
However, I want to achieve this by specifying all the layout for the control with xaml (not code). I know you can do simple things with ControlTemplates, but I'm trying add a command.
I've tried this a couple of times and given up.
The issues have been setting the content area, where the control can be used with various controls inside and binding the command which is implementing in xaml (with callong BindableProperty within xaml).
In your case you could use Bindable Property to pass value from ViewModel to your custom control .
1. Create a CustomControl with bindable property
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="App29.MyCustomControl"
x:Name="CustomView" // set name of view
>
<ContentView.Content>
<StackLayout>
</StackLayout>
</ContentView.Content>
</ContentView>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace App29
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyCustomControl : ContentView
{
public MyCustomControl()
{
InitializeComponent();
}
public static readonly BindableProperty ButtonClickCommandProperty =
BindableProperty.Create(nameof(ButtonClickCommand), typeof(ICommand), typeof(MyCustomControl));
public ICommand ButtonClickCommand
{
get => (ICommand)GetValue(ButtonClickCommandProperty);
set => SetValue(ButtonClickCommandProperty, value);
}
public static BindableProperty ButtonClickParameterProperty =
BindableProperty.Create(nameof(ButtonClickParameter), typeof(object), typeof(MyCustomControl));
public object ButtonClickParameter
{
get => (object)GetValue(ButtonClickParameterProperty);
set => SetValue(ButtonClickParameterProperty, value);
}
public static BindableProperty ButtonTitleProperty =
BindableProperty.Create(nameof(ButtonTitle), typeof(object), typeof(MyCustomControl),string.Empty);
public string ButtonTitle
{
get => (string)GetValue(ButtonTitleProperty);
set => SetValue(ButtonTitleProperty, value);
}
public static BindableProperty ChildLayoutProperty =
BindableProperty.Create(nameof(ChildLayout), typeof(View), typeof(MyCustomControl),propertyChanged: OnChildLayoutChanged);
public View ChildLayout
{
get => (View)GetValue(ChildLayoutProperty);
set => SetValue(ChildLayoutProperty, value);
}
static void OnChildLayoutChanged(BindableObject bindable, object oldValue, object newValue)
{
// Property changed implementation goes here
var Custom = bindable as MyCustomControl;
//child is the value that pass from viewmodel
var child = newValue as View;
// do something you want , like add it to stacklayout
var stack = Custom.Content as StackLayout;
stack.Children.Add(child);
}
//...other bindable property
}
}
in ContentPage
Now you can pass value to the custom control from ViewModel or code behind like following
<local:MyCustomControl ButtonClickCommand="{Binding xxx}" ButtonClickParameter="{Binding xxx}" ButtonTitle="{Binding xxx}" >
<local:MyCustomControl.Content>
<Button />
</local:MyCustomControl.Content>
</local:MyCustomControl>
For mode details about Bindable Property you could check https://learn.microsoft.com/en-us/xamarin/xamarin-forms/xaml/bindable-properties

Compiler error CS0029 at add a new element in app.xaml.cs

I have created a new element and app.xaml doesn't want to initialize it.
In my App.cs file I'm trying to set my TestPage(I've created TestPage by Add->New Item-> BlankPage) as Main Page but i'm getting this error "Severity Code Description Project File Line Suppression State Error CS0029 Cannot implicitly convert type 'smiles.Gridtesst' to 'Xamarin.Forms.Page'"
https://i.stack.imgur.com/fK8qg.png
P.S code
.xaml
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
x:Class="smiles.Gridtesst">
<ContentView.Content>
<StackLayout>
<Label Text="Hello Xamarin.Forms!" />
</StackLayout>
</ContentView.Content>
</ContentView>
app file
using System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace smiles
{
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new Gridtesst(); // error
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
cs file
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace smiles
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Gridtesst : ContentView
{
public Gridtesst()
{
InitializeComponent();
}
}
}
If you are adding a new page/element then you need to choose Content Page (not content View or another).

Xamarin Forms and PropertyChanged.Fody not updating UI

I have a Xamarin Forms project using MVVM in which I am attempting to use Fody and the PropertyChanged.Fody package. No matter what I try it simply does not work. I have spent the day searching for examples of projects using PropertyChanged.Fody and can't find any example sample code that actually works. Can someone help me out? Thanks.
I have added both Fody and PropertyChanged.Fody nugets to the project.
I have added the FodyWeavers.xml file to the Forms project which looks like...
<?xml version="1.0" encoding="utf-8"?>
<Weavers>
<PropertyChanged />
</Weavers>
My view is a standard ContentPage...
<ContentPage.BindingContext>
<viewmodels:GetStartedViewModel />
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout >
<Entry Text="{Binding TestMessage}" TextColor="Lime" FontSize="20" />
</StackLayout>
</ContentPage.Content>
I have tried implementing PropertyChanged.Fody on the ViewModel in 2 ways, both of which fail to work.
1)
public class GetStartedViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public string TestMessage { get; set; }
}
2)
[AddINotifyPropertyChangedInterface]
public class GetStartedViewModel
{
public string TestMessage { get; set; }
}

Using method from App class in separate form xamarin

I am a beginner, so this should be an easy fix for someone with experience.
I am a veterinarian trying to build an app for vets to use. I am trying to learn via youtube and previous posts online, but I cannot find a solution for my roadblock:
I am trying to call a method already written in the App class:
Settings form binds a volume of onhand penicillin.
Usage form displays that volume, and asks the user to enter a volume used.
On button click I need the onhand volume to be 'updated' but i can't call the method in the App class (which has a get and set)
I have simplified for easier evaluation:
App code behind:
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace methods
{
public partial class App : Application
{
private const string penicillin = "penicillin";
public App()
{
InitializeComponent();
MainPage = new NavigationPage(new MainPage());
}
public string Penicillin
{
get
{
if (Properties.ContainsKey(penicillin))
{
return Properties[penicillin].ToString();
}
return "";
}
set
{
Properties[penicillin] = value;
}
}
}
}
Settings Form:
<?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="methods.Settings">
<ContentPage.Content>
<StackLayout>
<Label Text="Penicillin Onhand" ></Label>
<Entry Text="{Binding Penicillin}" Keyboard="Numeric" ></Entry>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Settings Code behind:
using Xamarin.Forms;
namespace methods
{
public partial class Settings : ContentPage
{
public Settings()
{
InitializeComponent();
BindingContext = Application.Current;
}
}
}
Usage form:
<?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="methods.Usage">
<ContentPage.Content>
<StackLayout>
<Label Text="Penicillin Held" ></Label>
<Label x:Name="Held" Text="{Binding Penicillin}" ></Label>
<Label Text="Penicillin Used" ></Label>
<Entry x:Name="Using" Placeholder="ml" Keyboard="Numeric" ></Entry>
<Button Text="Use" Clicked="Used_Clicked"></Button>
</StackLayout>
</ContentPage.Content>
</ContentPage>
Usage Code behind:
using Xamarin.Forms;
namespace methods
{
public partial class Usage : ContentPage
{
public Usage()
{
InitializeComponent();
BindingContext = Application.Current;
}
void Used_Clicked(object sender, System.EventArgs e)
{
var VUsed = double.Parse(Using.Text);
var VHeld = double.Parse(Held.Text);
var Remaining = VHeld - VUsed;
//how do i code the following? Error:'App' does not contain definition for Penicillin????
App.Penicillin.value = Remaining;
}
}
}
You don't need to create a new instance of App - Xamarin Forms already maintains a reference to the current instance
((App)Application.Current).Penicillin = Remaining;

Xamarin Forms: Prism -- Issue with using unity IoC?

In my xamarin forms app using Prism MVVM Framework, How should I use IoC containers?
There are no
Container.Resolve<Interface,Implentation>
I think we need to resolve the IoC and initialize in app.xaml.cs. But I am not able to find proper way to do it.
Can anyone help me out ?
UPDATE:
PAGE:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="CoC.Core.Views.MenuPage">
<ContentPage.Content>
<ListView x:Name="info"
SeparatorVisibility="None"
SeparatorColor="Transparent"
HasUnevenRows="false"
RowHeight="50" BackgroundColor="#485366" >
<ListView.ItemTemplate>
<DataTemplate>
<!--<ImageCell Text="{Binding Title}" ImageSource="{Binding IconSource}" /> -->
<ViewCell>
<!--<Label Text="{Binding Title}" />-->
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ContentPage.Content>
</ContentPage>
ViewModel:
using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Collections.ObjectModel;
using Prism.Navigation;
namespace CoC.Core.ViewModels
{
public class MenuPageViewModel : BindableBase , INavigationAware
{
IMenuList _menuList;
public ObservableCollection<MenuItem> ConductList { get; set; }
public void OnNavigatedFrom(NavigationParameters parameters)
{
//throw new NotImplementedException();
}
public void OnNavigatedTo(NavigationParameters parameters)
{
//throw new NotImplementedException();
}
public MenuPageViewModel(IMenuList MenuList)
{
_menuList = MenuList;
ConductList = _menuList.GetMenuList();
}
}
}
APP:
using Prism.Unity;
using CoC.Core.Views;
namespace CoC.Core
{
public partial class App : PrismApplication
{
protected override void OnInitialized()
{
InitializeComponent();
//NavigationService.NavigateAsync("MainPage?title=Hello%20from%20Xamarin.Forms");
NavigationService.NavigateAsync("MenuPage");
}
protected override void RegisterTypes()
{
Container.RegisterTypeForNavigation<MainPage>();
Container.RegisterTypeForNavigation<RootPage>();
Container.RegisterTypeForNavigation<MenuPage>();
}
}
}
When I run this code, I am getting error in Main.cs of IOS pro
Error:
Foundation.MonoTouchException
NSInternalLnconistencyException Reason: Application window are expected to have a root view controller at the end of the application.
What you are looking for is an extension method in Unity. You need to add the using Microsoft.Practices.Unity namespace to your code file. The you can register your services using Container.Register<IService,MyService>().

Resources