Windows Phone 7 MVVM databinding form - windows-phone-7

I'm new to Windows Phone development, and currently have a simple form. I'm using the MVVM pattern and MvvmLight to run a command. The "Applicant" entity is always empty, and it looks like the 2 way databinding isn't working. Here is my code, I hope someone can point me in the right direction.
View
<Grid x:Name="LayoutRoot" Background="Transparent" DataContext="{Binding Applicant}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock x:Name="PageTitle" Text="create account" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<StackPanel>
<TextBlock FontSize="15" TextWrapping="Wrap" Margin="0,0,0,10" Text="Please register to create your applicant account. No information will be passed to third parties for any reason."></TextBlock>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="Forename" Width="100"></TextBlock>
<TextBox Width="350" BorderBrush="Red" DataContext="{Binding Forename, Mode=TwoWay}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="Surname" Width="100"></TextBlock>
<TextBox Width="350" x:Name="Surname" BorderBrush="Red" DataContext="{Binding Surname, Mode=TwoWay}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="Email" Width="100"></TextBlock>
<TextBox Width="350" x:Name="EmailAddress" BorderBrush="Red" DataContext="{Binding EmailAddress, Mode=TwoWay}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="Password" Width="100"></TextBlock>
<PasswordBox Width="350" x:Name="PassPhrase" BorderBrush="Red" DataContext="{Binding PassPhrase, Mode=TwoWay}"></PasswordBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="City" Width="100"></TextBlock>
<TextBox Width="350" x:Name="City" DataContext="{Binding City, Mode=TwoWay}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="State" Width="100"></TextBlock>
<TextBox Width="350" x:Name="County" DataContext="{Binding County, Mode=TwoWay}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="Country" Width="100"></TextBlock>
<TextBox Width="350" x:Name="Country" DataContext="{Binding Country, Mode=TwoWay}"></TextBox>
</StackPanel>
<StackPanel>
<Button Name="btnContact"
Content="Register"
DataContext="{Binding ElementName=this, Path=DataContext}"
Command="{Binding SaveApplicantCommand}"
Width="300"/>
</StackPanel>
</StackPanel>
</Grid>
</Grid>
View code behind
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
ApplicantViewModel vm = new ApplicantViewModel();
DataContext = vm;
}
View Model (the view model inherits from ViewModelBase which implements INotifyPropertyChanged)
public class ApplicantViewModel : ViewModelBase
{
public ApplicantViewModel()
{
SaveApplicantCommand = new RelayCommand(SaveApplicant);
Applicant = new Applicant();
}
public ICommand SaveApplicantCommand {get; set;}
void SaveApplicant()
{
if (string.IsNullOrEmpty(Applicant.Forename))
{
MessageBox.Show("Please enter a forename", "Oops...", MessageBoxButton.OK);
return;
}
db.AddObject("Applicants", Applicant);
db.BeginSaveChanges(OnChangesSaved, db);
}
void OnChangesSaved(IAsyncResult result)
{
}
private Applicant _applicant;
public Applicant Applicant
{
get
{
return _applicant;
}
set
{
if (_applicant != value)
{
_applicant = value;
RaisePropertyChanged("Applicant");
}
}
}
}
Whatever is entered into the Forename text box, I always get the error message because Forename is null.
***** UPDATE *********
Here is the Forename property in the model
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Data.Services.Design", "1.0.0")]
public string Forename
{
get
{
return this._Forename;
}
set
{
this.OnForenameChanging(value);
this._Forename = value;
this.OnForenameChanged();
this.OnPropertyChanged("Forename");
}
}

An ApplicantViewModel does not have a Forename property. Only Applicant has. So do the following:
<TextBox Width="350" BorderBrush="Red"
DataContext="{Binding Applicant.Forename, Mode=TwoWay}"/>
do the same with the other text boxes.

Related

Binding in Nested List Boxes to multiple classes

I'm making a nested listed box , basically because I need to bind multiple classes in a single list box , which I'm not able to do and hence the nested listed box.
Here's what I do in the XAML page :
<ListBox Name="abcd" Margin="10,0,30,0" ItemsSource="{Binding Title}" SelectionChanged="ListBox_SelectionChanged" Height="486" Width="404" FontSize="20">
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel Margin="0,0,10,0" Width="380" Height="140">
<Grid >
<TextBlock Text="{Binding cdata}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeLarge}" />
<ListBox Name="ab" ItemsSource="{Binding Description}" FontSize="14">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Width="380" Height="100">
<Grid>
<TextBlock Text="{Binding cdata}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeLarge}" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
where ListBox "abcd" has to be bound with class title and "ab" to the class Description.Both the classes have just one string field , "cdata".
In the xaml.cs I do :
abcd.ItemsSource=from article in root.openfooty.news.article
select new Classes.Title
{
cdata = article.title.cdata
};
ab.ItemSource = from article in root.openfooty.news.article
select new Classes.Description
{
cdata = article.description.cdata
};
binding with "abcd" works fine but with "ab" it says "the nam ab doesnt exist in the current context"
Any help would be much appreciated. Thanks :D
Why don't you write a single class like this
public class TitleDescription
{
public string title { get; set; }
public string description { get; set; }
}
and try the databinding ?
abcd.ItemsSource=from article in root.openfooty.news.article
select new Classes.TitleDescription
{
title = article.title.cdata,
description = article.description.cdata
};
And have only one list box like this
<ListBox Name="abcd" Margin="10,0,30,0" SelectionChanged="ListBox_SelectionChanged" Height="486" Width="404" FontSize="20">
<ListBox.ItemTemplate>
<DataTemplate >
<StackPanel Margin="0,0,10,0" Width="380" Height="140">
<Grid >
<TextBlock Text="{Binding description}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeLarge}" />
<TextBlock Text="{Binding title}" TextWrapping="Wrap" FontSize="{StaticResource PhoneFontSizeLarge}" />
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

get items in listboxitem

I have an xaml code about listbox object:
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="FirstListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid>
<TextBlock Text="{Binding LineOne}" TextWrapping="NoWrap" Margin="50,0,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="NoWrap" Margin="12,60,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<CheckBox VerticalAlignment="Top" Margin="0,-5,0,0"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
i was get my listboxitem by the code :
ListBoxItem item = this.list.ItemContainerGenerator.ContainerFromIndex(2) as ListBoxItem;
but i don't know how to get all items in this listbox item (including textblock and checkbox option).
please help me. thanks all.
Ideally, you'd want to have your checkbox bound to a property of your item data model, so for example, you may have...
public string LineOne { get; set; }
public string LineTwo { get; set; }
public bool MyBooleanValue { get; set; }
and then
<ListBox x:Name="FirstListBox" Margin="0,0,-12,0" ItemsSource="{Binding Items}" SelectionChanged="FirstListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid>
<TextBlock Text="{Binding LineOne}" TextWrapping="NoWrap" Margin="50,0,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock Text="{Binding LineTwo}" TextWrapping="NoWrap" Margin="12,60,0,0" Style="{StaticResource PhoneTextSubtleStyle}"/>
<CheckBox Checked="{Binding MyBoolValue, Mode=TwoWay}" VerticalAlignment="Top" Margin="0,-5,0,0"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Then you can pull back the DataContext for the item you are currently looking at (on a tap method or similar), or when you parse through your "Items" collection, all the checkbox states will be in the child objects for you already.

Image not showing in grid

In my App I want to display a picture inside a listbox, which is linked to objects through databinding.
However, the picture isn't showing up for some reason, and I can't seem to spot the error.
I know the picture is in the object, because if I add a new Image object to the XAML, and in code set its source to one of the images from an object, it shows it.
Below is my code in steps:
foreach (Indtastning indt in listBoxIndhold.ItemsSource)
{
byte[] data = Convert.FromBase64String(indt.imageName);
Stream memStream = new MemoryStream(data);
WriteableBitmap wbimg = PictureDecoder.DecodeJpeg(memStream);
indt.picture = new Image();
indt.picture.Source = wbimg;
//Below is my test image, which shows the picture correctly.
testimage.Source = indt.picture.Source;
}
My XAML with the Image:
<ListBox x:Name="listBoxIndhold" Grid.Row="0"
ItemsSource="{Binding .}"
ScrollViewer.VerticalScrollBarVisibility="Visible" >
<ListBox.ItemTemplate>
<DataTemplate >
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ShowGridLines="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Mode=OneWay, Path=name}" Grid.Column="0"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Style="{StaticResource PhoneTextSmallStyle}"
TextWrapping="Wrap" FontSize="24">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Tag="{Binding Mode=OneWay, Path=name}" Header="Rediger" Click="MenuItem_Click" />
<toolkit:MenuItem Tag="{Binding Mode=OneWay, Path=name}" Header="Slet" Click="MenuItem_Click_1"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
<TextBlock Text="{Binding Mode=OneWay, Path=description}" Grid.Column="1"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Style="{StaticResource PhoneTextSmallStyle}" TextWrapping="Wrap"
FontSize="24">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Tag="{Binding Mode=OneWay, Path=name}" Header="Rediger" Click="MenuItem_Click" />
<toolkit:MenuItem Tag="{Binding Mode=OneWay, Path=name}" Header="Slet" Click="MenuItem_Click_1"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
<Image Source="{Binding Mode=OneWay, Path=picture}" Grid.Column="2" VerticalAlignment="Center" HorizontalAlignment="Center" Width="48" Height="48" />
<TextBlock Text="{Binding Mode=OneWay, Path=amount}" Grid.Column="3"
HorizontalAlignment="Stretch" VerticalAlignment="Center"
Style="{StaticResource PhoneTextSmallStyle}"
FontSize="24" >
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu>
<toolkit:MenuItem Tag="{Binding Mode=OneWay, Path=name}" Header="Rediger" Click="MenuItem_Click" />
<toolkit:MenuItem Tag="{Binding Mode=OneWay, Path=name}" Header="Slet" Click="MenuItem_Click_1"/>
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My Indtastning class:
[DataContract]
public class Indtastning
{
[DataMember]
public string name { get; set; }
[DataMember]
public double amount { get; set; }
[DataMember]
public string description { get; set; }
[DataMember]
public bool owes { get; set; }
[DataMember]
public string id { get; set; }
[DataMember]
public string imageName;
public Image picture;
//Constructor
public Indtastning(string id , string navn, double beløb, string beskrivelse, bool skylder)
{
this.name = navn;
this.description = beskrivelse;
this.amount = beløb;
this.owes = skylder;
this.id = id;
}
}
Can anyone spot what I'm doing wrong here?
It's really anoying as it's one of the last things I need to sort before launching the app.
Have you saved your images as the content or resource . If the image is resource you will not see it , set it to content and try again . Hope it may help
The problem was solved a long time ago.
See my comment above.

WP7 Tombstoning - Easy practice

I have a databound xml reader. MainPage is connected to DetailsPage: When user clicks on the name in Main Page, She gets the details of this name (Age, Gender, Date of Birth etc.) in the DetailsPage.
I am in trouble with tombstoning atm. When I click on windows button, then click on back button I get into an empty DetailsPage.
What would be the easiest way to solve this problem? I tried to use TombstoneHelper but it also shows empty page.
DetailsPage.xaml
<controls:PanoramaItem Header="" Margin="0,0,0,80">
<ScrollViewer>
<StackPanel>
<TextBlock TextWrapping="Wrap" Width="432" Style="{StaticResource PhoneTextExtraLargeStyle}" Margin="0,0,0,10" d:LayoutOverrides="Width" Foreground="#DEFFFFFF"><Run Text="Personal D"/><Run Text="e"/><Run Text="tails"/></TextBlock>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Name"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="username" TextWrapping="Wrap" Text="{Binding Name}" Foreground="#DEFFFFFF" />
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Age"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="age" TextWrapping="Wrap" Text="{Binding Age}" Foreground="#DEFFFFFF"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Nationality"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="country" TextWrapping="Wrap" Text="{Binding Country}" Foreground="#DEFFFFFF"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Country of Birth"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="cobirth" TextWrapping="Wrap" Text="{Binding Cobirth}" Foreground="#DEFFFFFF"/>
</StackPanel>
<StackPanel HorizontalAlignment="Left" Width="432" Orientation="Horizontal">
<TextBlock TextWrapping="Wrap" Margin="20,0,7,0" Foreground="#DEFFFFFF"><Run Text="Place of Birth"/><Run Text=":"/></TextBlock>
<TextBlock x:Name="fobirth" TextWrapping="Wrap" Text="{Binding Pobirth}" Foreground="#DEFFFFFF"/>
</StackPanel>
</StackPanel>
</ScrollViewer>
</controls:PanoramaItem>
DetailsPage.cs
using TombstoneHelper;
public User()
{
InitializeComponent();
SupportedOrientations = SupportedPageOrientation.Portrait;
}
protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
this.SaveState(); // <- first line
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
this.RestoreState(); // <- second line
}
Mainpage.Cs
private void UserListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
NavigationService.Navigate(new Uri("/DetailsPage.xaml", UriKind.Relative));
FrameworkElement root = Application.Current.RootVisual as FrameworkElement;
root.DataContext = (RosterItem)e.AddedItems[0];
((ListBox)sender).SelectedIndex = -1;
}
}
All things being equal Tombstone helper should just work. Remember that you need to have named your controls (with an x:Name attribute) for Tombstone helper to access them. Also make sure you are calling SaveState() in your NavigatedFrom() method and RestoreState() in NavigatedTo() (and not the other way round).
If that doesn't something must be wrong elsewhere in your code. We might be able to help if you post the relevant parts of your code.

Binding list Collection from a list collection in Window Phone 7

How to Binding list Collection from a list collection in Window Phone 7 while i am able to bind from a single list collection
First of all have item template in your Xaml.
Add Binding to it.
Define that binding property in your code.
Assign values to the defined property.
I am having a item template in my Xaml like this :
<Grid.RowDefinitions>
<RowDefinition Height="367*" />
</Grid.RowDefinitions>
<ListBox HorizontalAlignment="Stretch" Name="lstbNewOrders" Grid.Row="1" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid x:Name="itemTemplate" Background="Transparent" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<TextBlock FontSize="30" Name="txtEbeln" Text="{Binding ebeln}" Grid.Row="0" Grid.Column="0" FontWeight="Bold" />
<TextBlock FontSize="25" Name="txtCName" Text="{Binding cname}" Grid.Row="1" Grid.Column="0" />
<TextBlock FontSize="25" Name="txtDate" Text="{Binding date}" Grid.Row="1" Grid.Column="1" HorizontalAlignment="Right" TextAlignment="Right"/>
<StackPanel Height="30" Name="stkPanel01" HorizontalAlignment="Right" Grid.Row="0" Grid.Column="1">
<TextBlock FontSize="25" Name="txtNetw" Text="{Binding netw}" HorizontalAlignment="Right" TextAlignment="Right"/>
</StackPanel>
<TextBlock FontSize="25" Name="txtVName" Text="{Binding vname}" Grid.Row="2" Grid.Column="0" />
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
In my code file i will define the binding like this:
public class itemListForListBox
{
public string ebeln { get; set; }
public string cname { get; set; }
public string vname { get; set; }
public string netw { get; set; }
public string date { get; set; }
}
And provide values like this:
void fillList()
{
List<itemListForListBox> itemListbox = new List<itemListForListBox>();
itemListForListBox listItem;
for (int i = 0; i < 5;i++ )
{
listItem = new itemListForListBox();
listItem.ebeln = "Name "+i;
listItem.date = "Date "+i;
listItem.vname = "VName "+i;
listItem.netw = "Amount "+ i;
listItem.cname = "CName "+i;
itemListbox.Add(listItem);
}
lstbNewOrders.ItemsSource = itemListbox;
}
Hope this might help you.
Thanks.
You can use the code below,
<ListBox Name="RouteListBox" ItemContainerStyle="{StaticResource RouteListBoxItemStyle}" SelectedItem="{Binding Model.SelectedRoute,Mode=TwoWay}" ItemsSource="{Binding RouteListCollection}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<command:EventToCommand Command="{Binding RouteItemSelectedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding RouteName}" Style="{StaticResource RoutesStyle}" Grid.Column="1" />
<Border Style="{StaticResource RouteCountBorder}" Visibility="Collapsed" Grid.Column="2">
<TextBlock Style="{StaticResource RoutesCount}" Visibility="Collapsed" Text="{Binding ShopCount,Mode=TwoWay}"></TextBlock>
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate></ListBox>
I take it you mean you have a collection of collections? In this case, you can nest your ItemsControls (or ListBox):
<ItemsControl ItemsSource={Binding Path=???}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- here is your nested itemscontrol -->
<ItemsControl ItemsSource={Binding Path=???}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<!-- your content goes here -->
</DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Let say we have a ListBox lstbx and a collection lets say
List <String> listdata = new List<String>();
we can add items to the collection by Add()
Ex-
listdata.Add("Nazi 1");
or
forloop(expression)
{
listdata.Add("vale")
}
then we can assign assign the collection directly to the listbox' item Source
ex.
lstbx.ItemSource=listdata;
//make sure if u are storing more than one variable in a single item of the collection ,you should create custom data template for the ListBox Item Template. !

Resources