windows phone 8 data binding to an array - xaml

I'm a windows phone 8 novice, struggling at the moment with xaml data-binding with arrays.
XAML:
<phone:LongListSelector x:Name="LocationsData" Margin="0,0,-12,0" ItemsSource="{Binding}">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17">
<TextBlock Text="{Binding name}" TextWrapping="NoWrap" Margin="12,0,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding vicinity}" TextWrapping="NoWrap" Margin="12,-6,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
.CS
LocationsData.DataContext = _array_of_locations;
The _array_of_locations has 4 items,
each of them is a valid JSON,
{
"geometry": {
"location": {
"lat": 12.923101,
"lng": 77.586057
}
},
"icon": "http://maps.gstatic.com/mapfiles/place_api/icons/restaurant-71.png",
"id": "9a769bc2faaa79fe0ffbd85c2c28446940153331",
"name": "Domino's Pizza",
"opening_hours": {
"open_now": false
},
"price_level": 1,
"rating": 2.9,
"reference": "CnRsAAAAsI0LvfwZ_RC8PEDsJS3TfKkRkTn7d_2_-vw8tu_SYBYCJk2CmKt6RyRJtO5mG0Weq-R0jSsmyQOWHjU45itlrH1cN89EqgIA9Vtmvcih1xi6ZwpNewqZ8mNCQWWLDJvcT3AQLHGnFcn4E9a30Gvs9xIQeKGVsrSOKLDx4vYCjixIKhoUOGeosCJIVFDmE3-3qIPcIM7PSCs",
"types": [
"restaurant",
"food",
"establishment"
],
"vicinity": "11th Main Road, Jayanagar, Bangalore"
}
It's not working, I'm getting lost with all the documentation as I don't come from a c# background. So how do I get this working?

The problem isn't the arrays here, it's the fact that the source of a data binding (i.e. the name and vicinity in {Binding name} and {Binding vicinity}) must be a property. The objects in your array don't have properties with names name and vicinity, so nothing gets shown. In fact, you might even see binding errors in the Output window in Visual Studio, mentioning that it couldn't find name and vicinity properties.
I suspect you have got four items in your LongListSelector, but because none of them have any text in them, they have zero size and you don't see them. Try adding a TextBlock with some static text (e.g. <TextBlock Text="X"/>) to your StackPanel to see if four Xs appear.
If you just need to show the JSON read-only, then it should be possible to deserialize the JSON to anonymous types. An anonymous type will then be created for each JSON object, with one (.NET) property for each property in the JSON object. See for example this question. With any luck that should work, however, I haven't tested it.

Related

Cannot bind my Converter class in my XAML command that pass parameter

This is my XAML that is trying to have my ListView pass a parameter to the ViewModel command.
xmlns:mvvm="http://www.galasoft.ch/mvvmlight"
<ListBox x:Name="MyListView" ItemsSource="{Binding Objects}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<mvvm:EventToCommand Command="{Binding MyCommand}"
PassEventArgsToCommand="True"
EventArgsConverter="{StaticResource ParamConverter }"
EventArgsConverterParameter ="{Binding Name}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And this is my converter:
public class ParamConverter : IEventArgsConverter
{
public object Convert(object value, object parameter)
{
var args = (SelectionChangedEventArgs)value;
var name = parameter as string;
return (string)name.ToString();
}
}
But I got the following error:
The resource "ParamConverter" could not be resolved
Your converter is not declared in XAML, you should add something like
<ListBox.Resources>
<yournamespace:ParamConverter x:Key="ParamConverter"/>
</ListBox.Resources>
inside your listbox tags.
EDIT: I'm not an expert at all, so bear with my "imprecise" terms if any. I think you're missing something: there is no magic that allows your XAML to be aware of your C#. You need to tell XAML that somewhere in your code (in yournamespace) there will be a ParamConverter object, that can be referenced inside xaml with ParamConverter key.
You can declare your resource locally inside ListBox tags as suggested, or at outer scope if needed.
Once resource is declared inside XAML, you can access it via StaticResource.

UWP : Setting the Width and Height of controls as percentage values

I am trying to use a StackPanel control to display some overview options. I need to have this control using 20% of the window width when the MinWindowWidth is greater than 768px. When this is run on mobile I need the control to fill the width of the screen.
I tried as suggested in this question to try and set a value in percentage. However, I get the error - "* string cannot be converted to length".
Here is my XAML -
<StackPanel x:Name="OverviewStack">
<RelativePanel>
<StackPanel Margin="10" x:Name="User" Orientation="Horizontal">
<Ellipse Margin="5" Width="50" Height="50">
<Ellipse.Fill>
<ImageBrush>
<ImageBrush.ImageSource>
<BitmapImage UriSource="Assets/insp.jpg" />
</ImageBrush.ImageSource>
</ImageBrush>
</Ellipse.Fill>
</Ellipse>
<TextBlock Margin="5" VerticalAlignment="Center" Text="Ajay Kelkar" />
</StackPanel>
<StackPanel Margin="10" x:Name="Options" Orientation="Vertical">
<TextBlock Margin="5" Text="Sample text" />
</StackPanel>
</RelativePanel>
</StackPanel>
Is a percentage value not possible in UWP? Or am I doing something wrong?
You need to determine which platform you're currently on, and set the value accordingly.
This sounds like a converter.
Since you only have 1 project for UWP you'll need to check in the converter which platform you're on. such info can be acquired as such:
if (AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile")
{
//Act accordingly
}
So I think you'd like to do something like this:
public object Convert(object value, Type targetType, object parameter, string language)
{
// bind the width as the value the converter is set upon
var width = double.Parse(value.ToString());
if (AnalyticsInfo.VersionInfo.DeviceFamily == "Windows.Mobile")
{
return width;
}
// You weren't clear exactly regarding the 768px thing so act accordingly here
return width * 0.2d;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
throw new NotImplementedException();
}

Why is this XAML failing with "The property "Content" can only be set once."?

I've got this XAML:
<AppBarButton Icon="Protected" Label="Privacy Policy" >
<AppBarButton.Flyout>
<StackPanel>
<Flyout>
<TextBlock Text="Photrax extracts information from images you load into it. The information it extracts includes location information (where the photos were taken, when that is available) and the date and time the photo was taken. This data is stored in a local/internal/embedded (SQLite) database. This data is not stored in the cloud but only on your local device." TextWrapping="Wrap" FontSize="26" FontFamily="Verdana">
</TextBlock>
<TextBlock Text="To reiterate: Your data is not shared with anyone else. It is stored only on the device from which you use Photrax." TextWrapping="Wrap" FontSize="26" FontFamily="Verdana">
</TextBlock>
</Flyout>
</StackPanel>
</AppBarButton.Flyout>
</AppBarButton>
...which fails with, "The property "Content" can only be set once."
Why is there a problem with this, when the following XAML, which is basically the same, compiles fine:
<AppBarButton Icon="MapPin" Label="Colors In Use" Tapped="appbarbtnPhotosetColorMapping_Tapped">
<AppBarButton.Flyout>
<Flyout>
<StackPanel Background="Azure">
<TextBlock Text="Photoset:Pushpin Color Legend" TextWrapping="Wrap" FontSize="26" FontFamily="Verdana"></TextBlock>
<TextBlock x:Name="textblock0" Text="Unused" Foreground="Red" FontFamily="Segoe UI" FontSize="13" Margin="4" />
. . .
?
I get other err msgs with that xaml, too (about the following types being expected: flyoutbase and uielement), but I think it's the Content business that is giving me the business.
I pasted the problem code into kaxaml, but it doesn't even know what an AppBarButton is, and complained about that being an invalid element.
UPDATE
I can't test it yet, but I'm thinking that what Abdallah means is that I need to change this:
<StackPanel>
<Flyout>
. . .
</Flyout>
</StackPanel>
...to this:
<Flyout>
<StackPanel>
. . .
</StackPanel>
</Flyout>
You have two problems here :
1) The property "Content" can only be set once. :
You can't set the content for <Flyout> </Flyout> more than once and you set the content twice (Two TextBlocks) in first XAML code and in the working XAML once(One StackPanel), According to MSDN :
<Flyout>
singleUIElement
</Flyout>
singleUIElement :
A single object element that declares the content. This must be an
object that has UIElement in its hierarchy (plain strings don't work).
This can be a container, such as a Panel derived class, so that
multiple content items within the Flyout can be arranged in layout.
2) The following type was expected: "FlyoutBase".
You can't set Flyout property to any class that not derived from FlyoutBase class (i.e only Flyout and MenuFlyout ). you set the Flyout property in first XAML code to StackPanel and in the working XAML to Flyout .

RepeaterView<T> in Xamarin Forms Labs

I'm trying to figure out the RepeaterView in Xamarin Forms Labs.
THE BACKGROUND
I have a simple entity called Entry that has property called Notes
class Entry
{
public string Notes { get; set; }
}
In the common PCL, I've inherited from the RepeaterView to make it non-generic.
class EntryRepeater : Xamarin.Forms.Labs.Controls.RepeaterView<MyKids.Core.Entities.Entry>
{
}
And the XAML of the page where I'm trying to use the repeater looks like this
<rep:EntryRepeater ItemsSource="{Binding Entries}">
<rep:EntryRepeater.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<StackLayout>
<Label Text="{Binding Notes}" />
</StackLayout>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</rep:EntryRepeater.ItemTemplate>
</rep:EntryRepeater >
where Entries is an ObservableCollection.
THE ISSUE
The problem is that the binding in the DataTemplate seems to point to the main model and not to one item in the collection. BUT it is repeated the correct number of times.
[0:] Binding: 'Notes' property not found on 'MyApp.ViewModels.EntryListViewModel', target property: 'Xamarin.Forms.Label.Text'
To circle back to this question, this was actually an error in earlier versions of Xlabs. It's now fixed and the code above does work.

How do I refer to simple strings bound to a Silverlight Toolkit ListPicker in a DataTemplate?

I am styling the ListPicker with a DataTemplate. All the examples I have read assume that the ListItems are bound complex objects and so can refer to properties on the objects using the usual Binding Property syntax. e.g.
this.myListPicker.Items.Add(new Profile() { Name = "Joe",
Occupation="Button pusher" });
and in the XAML,
<DataTemplate>
<StackPanel>
<TextBox Text="{Binding Name}" />
<TextBox Text="{Binding Occupation}" />
</StackPanel>
</DataTemplate>
However my ListPickers are bound to a List of simple strings and there does not seem to be a property on the string that actually refers to the string.
How do I get a handle to the string inside the DataTemplate so that I can assign them to a e.g. TextBox in the template?
In the example code you show, you do actually have a "complex" object, a Profile, and the binding you specify should work.
If you really just have strings as the items, then the binding in your ItemTemplate would look like:
<TextBox Text="{Binding }" />
The relevant detail is that all ItemsControls (and ListPicker seems to be one) set the DataContext of the view of each item to the item. The binding syntax, above, means "bind to the source itself", and, unless otherwise specified (like with Source or RelativeSource, etc.), the source of any binding is the DataContext.
MSDN has more details here.