I am using caliburn micro, but cannot Action in the SelectedItemChanged - windows-phone-8

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'?

Related

Showing Marker on list of maps added in list view in Xamarin forms

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>

Display Data from API on screen in a decent form

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

UserControl communication with its parent page on Windows 8.1

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++;
}

How to de-serialize json in c#?

I am trying to deserialize json, I'm getting an error:
"An exception of type 'Newtonsoft.Json.JsonSerializationException' occurred in Newtonsoft.Json.DLL but was not handled in user code"
My code:
public void w_StandingsDownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (!string.IsNullOrEmpty(e.Result))
{
JsonSerializer jc = new JsonSerializer();
// var o = jc.Deserialize<RootObjectStandings>(e.Result);
var root3 = JsonConvert.DeserializeObject<RootObjectStandings>(e.Result);
// var root2 = JsonConvert.DeserializeObject<Headline>(e.Result);
football f = new football();
f.StandingList.ItemsSource = root3.info;
f.progressbar1.IsEnabled = false;
f.progressbar1.IsIndeterminate = false;
f.progressbar1.Visibility = Visibility.Collapsed;
}
}
Class:
public class RootObjectStandings
{
public int position { get; set; }
public int team_id { get; set; }
public string team { get; set; }
public string teamshort { get; set; }
public string teampath { get; set; }
public int played { get; set; }
public int won { get; set; }
public int drawn { get; set; }
public int lost { get; set; }
public int #for { get; set; }
public int against { get; set; }
public int difference { get; set; }
public Home home { get; set; }
public Away away { get; set; }
public int points { get; set; }
public string info { get; set; }
}
and xaml code:
<ListBox x:Name="StandingList" FontFamily="Arial Black" VerticalAlignment="Center" Margin="-6,0,0,-26" Height="610" RenderTransformOrigin="0.5,0.5" Background="{x:Null}" Opacity="0.8">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Button Style="{StaticResource ButtonStyle1}" Width="450" Height="Auto" Background="Black" BorderBrush="Transparent" FontWeight="Bold" FontSize="23" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,0,0,5" Opacity="0.95" Foreground="White">
<StackPanel>
<TextBlock TextWrapping="Wrap" FontFamily="Segoe WP Black" Foreground="White" FontSize="18" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" TextAlignment="Left" Width="350" Height="150">
<Run FontSize="23" Text="{Binding info}" />
<LineBreak/>
<Run Text="{Binding position}" FontWeight="Normal" FontSize="16" FontFamily="Segoe WP SemiLight"/>
</TextBlock>
</StackPanel>
</Button>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
What is going wrong? help

Bind ImageSource in Windows Phone

I am Using LazyListBox as given below.There is an Image in Data Template.And I am not able to Bind the ImageUrl.How can i Bind ImageSource.
<lazy:LazyListBox x:Name="d" ItemSource={Binding ProductImageLIst}>
<lazy:LazyListBox.LoadedItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Product_Id}" Foreground="Black"></TextBlock>
<Image x:Name="img" Source="{Binding Path=ImageUrl}"></Image>
</StackPanel>
</DataTemplate>
</lazy:LazyListBox.LoadedItemTemplate>
</lazy:LazyListBox>
And my ProductImageList Class is Shown Below
public class ProductImageList
{
public string ImageId { get; set; }
public string ImageUrl{ get; set; }
public string Product_Id { get; set; }
public string Category_id { get; set; }
public ProductImageList()
{
}
public ProductImageList(string imageid, string imageurl, string productid,string catid)
{
this.ImageId = imageid;
this.ImageUrl = imageurl;
this.Product_Id = productid;
this.Category_id = catid;
}
}
Use BitmapImage to bind source of image in LazyListBox control. Here is the solution. If your 'ImageUrl' is a http url you should first download image from this url and create BitmapImage by downloaded image stream, and if your imageUrl is a relative url create BitmapImage as below.
<lazy:LazyListBox x:Name="d" ItemSource={Binding ProductImageLIst}>
<lazy:LazyListBox.LoadedItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Product_Id}" Foreground="Black"></TextBlock>
<Image x:Name="img" Source="{Binding Path=ImageSource}"></Image>
</StackPanel>
</DataTemplate>
</lazy:LazyListBox.LoadedItemTemplate>
</lazy:LazyListBox>
public class ProductImageList
{
public string ImageId { get; set; }
public string ImageUrl{ get; set; }
public string Product_Id { get; set; }
public string Category_id { get; set; }
public BitmapImage ImageSource{get;set;}
public ProductImageList()
{
}
public ProductImageList(string imageid, string imageurl, string productid,string catid)
{
this.ImageId = imageid;
this.ImageUrl = imageurl;
this.Product_Id = productid;
this.Category_id = catid;
this.ImageSource = new BitmapImage(new Uri(imageurl, UriKind.RelativeOrAbsolute));
}
}