I'm working on a Universal App (windows 8.1).
I'd like to increment the property "Number" in my main page by clicking on the button in my UserControl.
(the above code is an example)
Mainpage.xaml :
<Page
x:Class="App3.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:uc="using:App3"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<uc:MyUserControl1></uc:MyUserControl1>
</Grid>
</Page>
Mainpage.xaml.cs :
namespace App3
{
public sealed partial class MainPage : Page
{
public int number { get; set; }
public MainPage()
{
this.InitializeComponent();
this.NavigationCacheMode = NavigationCacheMode.Required;
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
}
}
}
MyUserControl1.xaml
<UserControl
x:Class="App3.MyUserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App3"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid>
<StackPanel>
<TextBlock Text="Test" />
<TextBlock Text="Test" />
<TextBlock Text="Test" />
<Button Height="20"
Width="50"
Content="click"
Click="Button_Click"/>
<TextBlock Text="Test" />
<TextBlock Text="Test" />
<TextBlock Text="Test" />
</StackPanel>
</Grid>
</UserControl>
MyUserControl1.xaml.cs
namespace App3
{
public sealed partial class MyUserControl1 : UserControl
{
public MyUserControl1()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//TODO : ?
}
}
}
How can I do ? I don't want to use a property in app.cs...
Define a Dependency property in your usercontrol and bind this property to one property in your MainPage.by using dependency property your usercontrol will behave like an independent control just like some Button Control etc. It will give you a example how to use DependencyProperty too.
In your usercontrol add this code
public sealed partial class MyUserControl1 : UserControl
{
public MyUserControl1()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//TODO : ?
Caption = 2;
}
public int Caption
{
get { return (int)GetValue(CaptionProperty); }
set { SetValue(CaptionProperty, value); }
}
public static readonly DependencyProperty CaptionProperty =
DependencyProperty.Register("Caption", typeof(int), typeof(MyUserControl1),
new PropertyMetadata(0, null));
}
In you MainPage.xaml bind this caption property like this.
<Grid>
<uc:MyUserControl1 Caption="{Binding SomeValue,Mode=TwoWay}" ></uc:MyUserControl1>
</Grid>
Add property to MainPage.Xaml.cs like this.
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
this.DataContext = this;
}
public string SomeValue
{
set
{
string df = value; // put a break point here and check
}
}
}
Now put a break point on Set and see if is it changing or not.
Create an event in your Usercontrol like so:
namespace App3
{
public sealed partial class MyUserControl1 : UserControl
{
public event EventHandler ButtonClicked;
public MyUserControl1()
{
this.InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
//TODO : ?
if (ButtonClicked != null)
ButtonClicked(this, new EventArgs());
}
}
}
then in your XAML for the MainPage set an eventhandler for ButtonClicked Event in the usercontrol like so
<uc:MyUserControl1 ButtonClicked="Increment_Click"></uc:MyUserControl1>
Then in the code Behind for your MainPage create the Increment_Click method:
private void Increment_Click(Object sender, RoutedEventArgs e)
{
number++;
}
Related
I have added a map control under the grid view to show different locations, I want to show a pin or markedr on each of these maps. I am binding in the list the longitude and latitude against each location under the position object.
Below is the XAML:
<grial:GridView
Grid.Row="1"
ColumnSpacing="15"
RowSpacing="15"
ColumnCount="{
grial:OnOrientationInt
PortraitPhone=1,
LandscapePhone=2,
PortraitTablet=2,
LandscapeTablet=2,
PortraitDesktop=3,
LandscapeDesktop=3
}"
VerticalOptions="FillAndExpand"
ItemsSource="{ Binding Branches }">
<grial:GridView.ItemTemplate>
<DataTemplate>
<local:ArticleColumnItemTemplate>
</local:ArticleColumnItemTemplate>
</DataTemplate>
</grial:GridView.ItemTemplate>
</grial:GridView>
Below is the contentView:
<ContentView.Content>
<Grid
Padding="0">
<grial:CardView
BackgroundColor="White"
Padding="10"
CornerRadius="15"
RowSpacing="5"
Margin="{
grial:OnOrientationThickness
Default='5,5,5,5',
LandscapePhone='5,5,5,5'
}">
<grial:CardView.RowDefinitions>
<RowDefinition
Height="Auto" />
</grial:CardView.RowDefinitions>
<maps:Map x:Name="map"
HeightRequest="280"
MapType="Satellite"
Grid.Row="0">
<maps:Map.Pins>
<maps:Pin
Address="{Binding Branches.address.street1}"
Label="Label1"
Position="{Binding Branches.Position}"
Type="Place">
</maps:Pin>
</maps:Map.Pins>
</maps:Map>
</grial:CardView>
</Grid>
</ContentView.Content>
Below is my View model which I am binding on Page load
public class MapPageViewModel : INotifyPropertyChanged
{
private readonly string _variantPageName;
public event PropertyChangedEventHandler PropertyChanged;
public List<Branches> _branches;
public List<Branches> Branches
{
get => _branches;
set
{
_branches = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Branches"));
}
}
}
public MapPageViewModel()
{
LoadData();
}
public async void LoadData()
{
Branches = await GetApiCalls.ServiceClientInstance.GetBranches();
foreach(Branches item in Branches)
{
item.Position = new Position(Convert.ToDouble(item.address.location.latitude),
Convert.ToDouble(item.address.location.longitude));
}
}
}
Below are the branch and address classes:
public class Branches : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public string branchName { get; set; }
public Address address { get; set; }
public Position _position;
public Position Position
{
get => _position;
set
{
_position = value;
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Position"));
}
}
}
}
public class Address
{
public string street1 { get; set; }
public string street2 { get; set; }
public Location location { get; set; }
}
public class Location
{
public double? latitude { get; set; }
public double? longitude { get; set; }
}
I have also debug and got the position object being initiated with longitude and latitude but pins are not visible on each of these maps.
your binding expression is wrong
<maps:Pin Address="{Binding Branches.address.street1}"
Label="Label1"
Position="{Binding Branches.Position}"
Type="Place">
</maps:Pin>
it should be
<maps:Pin Address="{Binding address.street1}"
Label="Label1"
Position="{Binding Position}"
Type="Place">
</maps:Pin>
i showed API data on screen but in JSON format. Now i want it to look a little bit decent. What changes can i made and in which section.
Here is the API data:
public class myuser
{
public int id { get; set; }
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string avatar { get; set; }
}
}
design Page xaml:
<StackLayout Padding="20">
<Editor Text="id" IsReadOnly="True"/>
<Editor Text="First name" IsReadOnly="True"/>
<Editor Text="Last name" IsReadOnly="True"/>
<Editor Text="Email" IsReadOnly="True"/>
<Image Source="https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg">
</Image>
<Label Text="show json"
x:Name="displaylabel"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
xaml.cs Here i called the API and showed it in JSON format
private static readonly HttpClient client = new HttpClient();
// private String data;
public String show;
//String responseString;
public Data(String data)
{
InitializeComponent();
Task.Run(async () => await GetinfoAsync());
var ID = new Editor { Text = "Id", IsReadOnly = true };
var FirstName = new Editor { Text = "first name", IsReadOnly = true };
var LastName = new Editor { Text = "lastname", IsReadOnly = true };
var Email = new Editor { Text = "email", IsReadOnly = true };
var Avatar = ImageSource.FromUri(new Uri("https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg"));
}
public async Task GetinfoAsync()
{
var responseString = await
client.GetStringAsync("https://reqres.in/api/users/2");
show = responseString;
// DisplayAlert("text", responseString, "ok");
Device.BeginInvokeOnMainThread(() => {
displaylabel.Text = show;
});
}
#Sajawal Zubairi
Please try this code it will help you to find your solution:
First, need to install the Newtonsoft.Json package in your project.
XAML Code:-
<StackLayout Padding="20">
<Editor Text="id" IsReadOnly="True"/>
<Editor Text="First name" IsReadOnly="True"/>
<Editor Text="Last name" IsReadOnly="True"/>
<Editor Text="Email" IsReadOnly="True"/>
<Image Source="https://s3.amazonaws.com/uifaces/faces/twitter/josephstein/128.jpg">
</Image>
<Label Text="show json"
x:Name="displaylabel"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
C# Code:-
public partial class MainPage : ContentPage
{
private static readonly HttpClient client = new HttpClient();
public MainPage()
{
InitializeComponent();
GetinfoAsync();
}
public async Task GetinfoAsync()
{
var responseString = await client.GetStringAsync("https://reqres.in/api/users/2");
myuserResponse result = JsonConvert.DeserializeObject<myuserResponse>(responseString);
// DisplayAlert("text", responseString, "ok");
if (result != null)
{
Device.BeginInvokeOnMainThread(() =>
{
displaylabel.Text = "Id:- " + result.Data.id + "\nEmail:- " + result.Data.email + "\nFirst Name:- " + result.Data.first_name + "\nLast Name:- " + result.Data.last_name + "\nImage:- " + result.Data.avatar;
});
}
}
}
API Data Model :-
public class myuser
{
public int id { get; set; }
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string avatar { get; set; }
}
public class myuserResponse
{
public myuser Data { get; set; }
}
OUTPUT Look like Below Image:
I hope the above code will be useful for you.
Thank You
You can achive your requirement using MVVM approach below is my code will help you
ViewModel code
public class MainPageViewModel : INotifyPropertyChanged
{
private static readonly HttpClient client = new HttpClient();
private UserDTO user;
public UserDTO UserData
{
get { return user; }
set
{
user = value;
OnPropertyChanged();
}
}
public MainPageViewModel()
{
GetUserData();
}
public async Task GetUserData()
{
var responseString = await client.GetStringAsync("https://reqres.in/api/users/2");
UserDTOResponse result = JsonConvert.DeserializeObject<UserDTOResponse>(responseString);
// DisplayAlert("text", responseString, "ok");
if (result != null)
{
UserData = result.Data;
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
View(XAML code)
<Grid Margin="20,50">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Editor Grid.Row="0" Grid.Column="0" Text="id" IsReadOnly="True"/>
<Editor Grid.Row="0" Grid.Column="1" Text="{Binding UserData.id}" IsReadOnly="True"/>
<Editor Grid.Row="1" Grid.Column="0" Text="First name" IsReadOnly="True"/>
<Editor Grid.Row="1" Grid.Column="1" Text="{Binding UserData.first_name}" IsReadOnly="True"/>
<Editor Grid.Row="2" Grid.Column="0" Text="Last name" IsReadOnly="True"/>
<Editor Grid.Row="2" Grid.Column="1" Text="{Binding UserData.last_name}" IsReadOnly="True"/>
<Editor Grid.Row="3" Grid.Column="0" Text="Email" IsReadOnly="True"/>
<Editor Grid.Row="3" Grid.Column="1" Text="{Binding UserData.email}" IsReadOnly="True"/>
<Editor Grid.Row="4" Grid.Column="0" Text="Image" IsReadOnly="True"/>
<Image Grid.Row="4" Grid.Column="1" HeightRequest="100" WidthRequest="100" Source="{Binding UserData.avatar}"/>
</Grid>
Models
public class UserDTO
{
public int id { get; set; }
public string email { get; set; }
public string first_name { get; set; }
public string last_name { get; set; }
public string avatar { get; set; }
}
public class UserDTOResponse
{
public UserDTO Data { get; set; }
}
Output
enter image description here
I hope it will help you.
Thank you
Can anyone please suggest binding for TextView inside ViewPager's fragment.
Please have look into below code for investigation.
ViewPager's fragment resource file (about_fragment.axml)
Here i'm trying to bind AboutDetail with ViewModel.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:local="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="#android:color/white">
<TextView
android:id="#+id/idAboutDetail"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="32.5dp"
android:layout_marginLeft="25dp"
android:layout_marginRight="8dp"
android:textColor="#android:color/black"
android:textSize="17sp"
local:MvxBind="Text AboutDetail"/>
</LinearLayout>
ViewPager's fragment VM
DetailViewModel belong to DetailFragment which contains ViewPager.
[AddINotifyPropertyChangedInterface]
public class AboutDetailViewModel : MvxViewModel<DetailViewModel>
{
public override void Prepare(DetailViewModel parameter)
{
AboutDetail = "Yes loaded";
}
private string _aboutDetail;
public string AboutDetail
{
get
{
return _aboutDetail;
}
set
{
_aboutDetail = value;
RaisePropertyChanged(() => AboutDetail);
}
}
}
ViewPager's Fragment
public class UCAboutFragment :BaseFragment<AboutDetailViewModel>
{
protected override int FragmentId => Resource.Layout.fragment_details_about;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
View view = base.OnCreateView(inflater, container, savedInstanceState);
return view;
}
}
DetailFragment code which contains ViewPager.
DetailPagerAdapter pageAdapter = new DetailPagerAdapter(ChildFragmentManager);
ViewPager pager = thisView.FindViewById<ViewPager>(Resource.Id.viewpager);
pager.Adapter = pageAdapter;
TabLayout tabLayout = thisView.FindViewById<TabLayout>(Resource.Id.tabs);
tabLayout.SetupWithViewPager(pager);
DetailPagerAdapter
private class DetailPagerAdapter : FragmentPagerAdapter
{
private List<Android.Support.V4.App.Fragment> mFragmentList;
private List<string> mFragmentTitleList = new List<string>();
public SectionsPagerAdapter(Android.Support.V4.App.FragmentManager fm) : base(fm)
{
this.mFragmentList = new List<Android.Support.V4.App.Fragment>();
addFragment(new UCAboutFragment(), "About");
addFragment(new UCServicesFragment(), "Services");
addFragment(new UCInsuranceFragment(), "Insurance");
}
#region implemented abstract members of PagerAdapter
public override int Count
{
get
{
return mFragmentList.Count;
}
}
#endregion
#region implemented abstract members of FragmentPagerAdapter
public override Android.Support.V4.App.Fragment GetItem(int position)
{
return mFragmentList[position];
}
#endregion
public override ICharSequence GetPageTitleFormatted(int position)
{
return new Java.Lang.String(mFragmentTitleList[position].ToLower());
}
private void addFragment(Android.Support.V4.App.Fragment fragment, string title)
{
mFragmentList.Add(fragment);
mFragmentTitleList.Add(title);
}
}
BaseFragment
{
public abstract class BaseFragment : MvxFragment
{
protected Toolbar Toolbar { get; private set; }
protected BaseFragment()
{
RetainInstance = true;
}
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var ignore = base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(FragmentId, null);
return view;
}
protected abstract int FragmentId { get; }
}
public abstract class BaseFragment<TViewModel> : BaseFragment where TViewModel : class, IMvxViewModel
{
public new TViewModel ViewModel
{
get { return (TViewModel)base.ViewModel; }
set { base.ViewModel = value; }
}
}
}
In the Fragments you have in your ViewPager, you need to use BindingInflate to inflate your View:
public class UCAboutFragment :BaseFragment<AboutDetailViewModel>
{
protected override int FragmentId => Resource.Layout.fragment_details_about;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var _ = base.OnCreateView(inflater, container, savedInstanceState);
var view = this.BindingInflate(FragmentId, container, false);
return view;
}
}
BindingInflate is what discovers the binding expressions in your layout and connects the ViewModel with the View iteself.
I have tried to use this tutorial:
http://www.badlogicgames.com/forum/viewtopic.php?f=11&t=484#p2959
Firstly have declared private Toast render_toast = new Toast(7, 6);
After that putted render_toast.toaster(); to render.
I would like to use it in show, so I have put this to show():
render_toast.makeText("Game start", "font", Toast.COLOR_PREF.BLUE, Toast.STYLE.ROUND, Toast.TEXT_POS.middle_right, Toast.TEXT_POS.middle_down, Toast.MED);
It isn't working, gives no error message, only stop my application.
I have implemented Android-like toast for my project and decided to share it with you! Enjoy: Toast LibGDX (GitHub)
Create an interface for required methods in your game. Implement this method in your AndroidLauncher class, using libgdx handler. You can call these methods anywhere in your game for Android related UI.
You can follow this video for details,
https://www.youtube.com/watch?v=XxiT3pkIiDQ
This is how, I used it in my game.
//Defining interface for customized methods
public interface AndroidInterfaces {
public void toast(final String t);
}
//implementing the interface in android launcer
public class AndroidLauncher extends AndroidApplication implements AndroidInterfaces{
final AndroidLauncher context=this;
#Override
protected void onCreate (Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();
//if (Gdx.input.isPeripheralAvailable(Peripheral.Compass))
cfg.useCompass = true;
//cfg.useAccelerometer=true;
initialize(new MyGame(this), cfg);
}
#Override
public void toast(final String t) {
handler.post(new Runnable()
{
#Override
public void run() {
//System.out.println("toatsing in launcher run");
Toast.makeText(context, t, Toast.LENGTH_SHORT).show();
}
});
}
}
public class MyGame extends Game{
//16012016
//16012016 for toast
AndroidInterfaces aoi;
public MyGame(AndroidInterfaces maoi)
{
aoi=maoi;
}
public MyGame()
{
}
public boolean backpressed=false; //Universal flag to check back button press status , across screens.
.....
.....
}
public class MainMenuScreen implements Screen{
MyGame game;
float x,y,w,h,pw,gap;
float x1,y1; //coordinates for animation
//16012016
boolean toast=false;
float toasttimer=0;
public MainMenuScreen(MyGame gg) {
game = gg;
}
#Override
public void render(float delta) {
//16012016
if(toast)
{
toasttimer=toasttimer+delta;
}
.....
...//omitted
//16012016:Toast
if(toast)
{
if(toasttimer> 2.5)
Gdx.app.exit();
else if (Gdx.input.isKeyJustPressed(Keys.BACK)) //For double back press exit effect.
Gdx.app.exit();
}
else if (Gdx.input.justTouched()) {
game.setScreen(game.STS); //Setting another screen
}
//16012016
else if (Gdx.input.isKeyJustPressed(Keys.BACK))
if(!game.backpressed)
{
if(!toast)
{
toast=true; //if bsck button is just pressed in current screen then toasting..
game.aoi.toast("EXITING.THANKS FOR PLAYING!"); //Not relevant to desktop project, calling implemented method in androind launcher
}
}
}
else if(game.backpressed)
{
game.backpressed=false;
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
//16012016
toasttimer=0;
toast=false;
Gdx.graphics.setContinuousRendering(true);
}
#Override
public void hide() {
Gdx.input.setInputProcessor(null);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
}
My pivotPageViewModel
public class PivotPageViewModel : Conductor<IScreen>.Collection.OneActive
{
private readonly PivotItem1PageViewModel item1;
private readonly PivotItem2PageViewModel item2;
public PivotPageViewModel(PivotItem1PageViewModel item1, PivotItem2PageViewModel item2)
{
this.item1 = item1;
this.item2 = item2;
}
protected override void OnInitialize()
{
base.OnInitialize();
Items.Add(item1);
Items.Add(item2);
ActivateItem(item1);
}
}
PivotItem1
public class PivotItem1PageViewModel : Screen
{
public String DisplayName { get; set; }
public List<String> Item{ get; set; }
public PivotItem1PageViewModel (INavigationService navigationService)
: base(navigationService)
{
DisplayName = "Name";
Item= new List<String>();
Item.Add("one");
Item.Add("two");
Item.Add("three");
Item.Add("four");
}
public void SelectedItemChanged(String select)
{
Debug.WriteLine("HElllo!!! " + select);
}
}
XAML
<ListBox x:Name="Secretariat" Foreground="Black"
FontFamily="{StaticResource PhoneFontFamilyLight}"
FontSize="50" Margin="10,0,-14,0"
cal:Message.Attach="[Event SelectionChanged] = [Action SelectedItemChanged($this)]">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>`
My SelectedItemChanged not work when i use pivotitem, but when i use a page normal the SelectedItemChanged usually work
According Caliburn.Micro documentation :
$this - The actual ui element to which the action is attached
So most likely your select parameter is not a String but ListBox. Do you have any exception from Caliburn about 'action not found'?